All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fitnesse.slim.test.Bowling Maven / Gradle / Ivy

There is a newer version: 20241026
Show newest version
// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.slim.test;

import java.util.Arrays;
import java.util.List;

public class Bowling {
  private Game g;

  @SuppressWarnings("unchecked")
  public List doTable(List> table) {
    g = new Game();
    List rollResults = Arrays.asList("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
    List scoreResults = Arrays.asList("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
    rollBalls(table);
    evaluateScores(g, table.get(1), scoreResults);
    return Arrays.asList(rollResults, scoreResults);
  }

  private void evaluateScores(Game g, List object, List scoreResults) {
    for (int frame = 0; frame < 10; frame++) {
      int actualScore = g.score(frame + 1);
      int expectedScore = Integer.parseInt(object.get(frameCoordinate(frame)));
      if (expectedScore == actualScore)
        scoreResults.set(frameCoordinate(frame), "pass");
      else
        scoreResults.set(frameCoordinate(frame), String.format("Was:%d, expected:%s.", actualScore, expectedScore));
    }
  }

  private int frameCoordinate(int frame) {
    return frame < 9 ? frame * 2 + 1 : frame * 2 + 2;
  }

  private void rollBalls(List> table) {
    List rollRow = table.get(0);
    for (int frame = 0; frame < 10; frame++) {
      String firstRoll = rollRow.get(frame * 2);
      String secondRoll = rollRow.get(frame * 2 + 1);
      rollFrame(firstRoll, secondRoll);
    }
  }

  private void rollFrame(String firstRoll, String secondRoll) {
    if (firstRoll.equalsIgnoreCase("X"))
      g.roll(10);
    else {
      int firstRollInt = parseFirstRoll(firstRoll);
      parseSecondRoll(secondRoll, firstRollInt);
    }
  }

  private void parseSecondRoll(String secondRoll, int firstRollInt) {
    if (secondRoll.equals("/"))
      g.roll(10 - firstRollInt);
    else if (secondRoll.equals("-"))
      g.roll(0);
    else
      g.roll(Integer.parseInt(secondRoll));
  }

  private int parseFirstRoll(String firstRoll) {
    int firstRollInt = 0;
    if (firstRoll.equals("-"))
      g.roll(0);
    else {
      firstRollInt = Integer.parseInt(firstRoll);
      g.roll(firstRollInt);
    }
    return firstRollInt;
  }

  private class Game {
    int[] rolls = new int[21];
    int currentRoll = 0;

    public void roll(int pins) {
      rolls[currentRoll++] = pins;
    }

    public int score(int frame) {
      return new Scorer(frame).score();
    }

    private class Scorer {
      private int frame;
      private int score;
      private int firstBall;

      public Scorer(int frame) {
        this.frame = frame;
        score = 0;
        firstBall = 0;
      }

      public int score() {
        for (int f = 0; f < frame; f++)
          scoreFrame();
      
        return score;
      }

      private void scoreFrame() {
        if (isStrike(firstBall)) {
          scoreStrike();
        } else if (isSpare(firstBall)) {
          scoreSpare();
        } else {
          scoreNoMark();
        }
      }

      private void scoreNoMark() {
        score += twoBallsInFrame(firstBall);
        firstBall += 2;
      }

      private void scoreSpare() {
        score += 10 + nextBallForSpare(firstBall);
        firstBall += 2;
      }

      private void scoreStrike() {
        score += 10 + nextTwoBallsForStrike(firstBall);
        firstBall += 1;
      }

      private int twoBallsInFrame(int firstBall) {
        return rolls[firstBall] + rolls[firstBall + 1];
      }

      private int nextBallForSpare(int firstBall) {
        return rolls[firstBall + 2];
      }

      private int nextTwoBallsForStrike(int firstBall) {
        return rolls[firstBall + 1] + rolls[firstBall + 2];
      }

      private boolean isSpare(int firstBall) {
        return rolls[firstBall] + rolls[firstBall + 1] == 10;
      }

      private boolean isStrike(int firstBall) {
        return rolls[firstBall] == 10;
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy