--------- --------- --------- | X | | | 3 | / | | 4 | 5 | |---------| |---------| |---------| | 20 | | 34 | | 43 | --------- --------- ---------
package bowling;
import junit.framework.TestCase;
public class TestBowling extends TestCase {
public void testFirstFrame() {
//setup
BowlingLane scorer = new BowlingLane();
//assert
assertFrame(scorer, false, 1);
}
public void testDropPins_Strike() {
//setup
BowlingLane scorer = new BowlingLane();
//execute
scorer.dropPins(10);
//assert
assertFrame(scorer, false, 2);
}
public void testDropPins_IncompleteFrame() {
//setup
BowlingLane scorer = new BowlingLane();
//execute
scorer.dropPins(0);
assertFrame(scorer, false, 1);
}
public void testDropPins_CompleteFrame() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(0);
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, false, 2);
}
public void testDropPins_IncompleteSecondFrame() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(0);
scorer.dropPins(0);
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, false, 2);
}
public void testDropPins_CompleteSecondFrame() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(0);
scorer.dropPins(0);
scorer.dropPins(0);
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, false, 3);
}
public void testDropPins_LastFrame_IncompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, false, 10);
}
public void testDropPins_LastFrame_CompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(0);
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, true, 10);
}
public void testDropPins_LastFrame_Strike_IncompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
//execute
scorer.dropPins(10);
//assert
assertFrame(scorer, false, 10);
}
public void testDropPins_LastFrame_TwoStrikes_IncompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
//execute
scorer.dropPins(10);
//assert
assertFrame(scorer, false, 10);
}
public void testDropPins_LastFrame_Strike_CompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
//execute
scorer.dropPins(10);
//assert
assertFrame(scorer, true, 10);
}
public void testDropPins_LastFrame_Spare_IncompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(5);
//execute
scorer.dropPins(5);
//assert
assertFrame(scorer, false, 10);
}
public void testDropPins_LastFrame_Spare_CompleteGame() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(5);
scorer.dropPins(5);
//execute
scorer.dropPins(0);
//assert
assertFrame(scorer, true, 10);
}
private void assertFrame(BowlingLane scorer, boolean gameOver, int currentFrame) {
assertEquals("game over", gameOver, scorer.gameOver());
assertEquals("current frame", currentFrame, scorer.currentFramePosition());
}
public void testPinsDropped_NormalFrame_OneThrow() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(5);
scorer.dropPins(4);
//execute
String[] pinsDropped = scorer.pinsDropped(1);
//assert
assertPins(pinsDropped, "5", "4");
}
public void testPinsDropped_TwoThrows() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(5);
//execute
String[] pinsDropped = scorer.pinsDropped(1);
//assert
assertPins(pinsDropped, "5", "");
}
public void testPinsDropped_Strike() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(10);
//execute
String[] pinsDropped = scorer.pinsDropped(1);
//assert
assertPins(pinsDropped, "X", "");
}
public void testPinsDropped_Spare() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(4);
scorer.dropPins(6);
//execute
String[] pinsDropped = scorer.pinsDropped(1);
//assert
assertPins(pinsDropped, "4", "/");
}
public void testPinsDropped_LastFrame_OneThrow() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(4);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "4", "", "");
}
public void testPinsDropped_LastFrame_TwoThrows() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(2);
scorer.dropPins(6);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "2", "6", "");
}
public void testPinsDropped_LastFrame_Strike() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "X", "", "");
}
public void testPinsDropped_LastFrame_TwoStrikes() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "X", "X", "");
}
public void testPinsDropped_LastFrame_ThreeStrikes() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "X", "X", "X");
}
public void testPinsDropped_LastFrame_TwoStrikesPlusExtraThrow() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(5);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "X", "X", "5");
}
public void testPinsDropped_LastFrame_Spare() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(7);
scorer.dropPins(3);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "7", "/", "");
}
public void testPinsDropped_LastFrame_SparePlusExtraThrow() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(7);
scorer.dropPins(3);
scorer.dropPins(9);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "7", "/", "9");
}
public void testPinsDropped_LastFrame_SparePlusStrike() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(7);
scorer.dropPins(3);
scorer.dropPins(10);
//execute
String[] pinsDropped = scorer.pinsDropped(10);
//assert
assertPins(pinsDropped, "7", "/", "X");
}
private void assertPins(String[] pinsDropped, String firstThrow, String secondThrow) {
assertEquals("number of throws", 2, pinsDropped.length);
assertEquals("first throw", firstThrow, pinsDropped[0]);
assertEquals("second throw", secondThrow, pinsDropped[1]);
}
private void assertPins(String[] pinsDropped, String firstThrow, String secondThrow, String thirdThrow) {
assertEquals("number of throws", 3, pinsDropped.length);
assertEquals("first throw", firstThrow, pinsDropped[0]);
assertEquals("second throw", secondThrow, pinsDropped[1]);
assertEquals("third throw", thirdThrow, pinsDropped[2]);
}
public void testScore_EmptyFrame() {
//setup
BowlingLane scorer = new BowlingLane();
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "", score);
}
public void testScore_IncompleteFrame() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(7);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "", score);
}
public void testScore_CompleteFrame() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(7);
scorer.dropPins(2);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "9", score);
}
public void testScore_Strike_MissingThrows() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(10);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "", score);
}
public void testScore_Spare() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(5);
scorer.dropPins(5);
scorer.dropPins(1);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "11", score);
}
public void testScore_Strike() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(10);
scorer.dropPins(5);
scorer.dropPins(1);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "16", score);
}
public void testScore_TwoStrikes() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(3);
//execute
String score = scorer.score(1);
//assert
assertEquals("score", "23", score);
}
public void testScore_LastFrame_Empty() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "", score);
}
public void testScore_LastFrame_OneThrow() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(1);
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "", score);
}
public void testScore_LastFrame_TwoThrows() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(1);
scorer.dropPins(6);
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "7", score);
}
public void testScore_LastFrame_IgnoreThirdThrow() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(1);
scorer.dropPins(6);
scorer.dropPins(2);
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "7", score);
}
public void testScore_LastFrame_Strike() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(10);
scorer.dropPins(6);
scorer.dropPins(2);
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "18", score);
}
public void testScore_LastFrame_Spare() {
//setup
BowlingLane scorer = new LastFrameBowlingLane();
scorer.dropPins(4);
scorer.dropPins(6);
scorer.dropPins(2);
//execute
String score = scorer.score(10);
//assert
assertEquals("score", "12", score);
}
public void testScore_CumulativeScore() {
//setup
BowlingLane scorer = new BowlingLane();
scorer.dropPins(4);
scorer.dropPins(2);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(5);
//execute
String score = scorer.score(2);
//assert
assertEquals("score", "31", score);
}
public void testPerfectGame() {
BowlingLane scorer = new BowlingLane();
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
scorer.dropPins(10);
String score = scorer.score(10);
assertEquals("score", "300", score);
assertFrame(scorer, true, 10);
String[] pinsDropped = scorer.pinsDropped(1);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(2);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(3);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(4);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(5);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(6);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(7);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(8);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(9);
assertPins(pinsDropped, "X", "");
pinsDropped = scorer.pinsDropped(10);
assertPins(pinsDropped, "X", "X", "X");
}
}
|
package bowling;
import java.util.List;
class NullFrame extends Frame {
NullFrame(List<Frame> frames) {
super(frames);
}
Throw score() {
return new Throw(0);
}
}
|
package bowling;
class LastFrameBowlingLane extends BowlingLane {
LastFrameBowlingLane() {
this.currentFrame = frames.get(frames.size() - 1);
frames.set(frames.size() - 2, new NullFrame(frames));
}
}
|
package bowling;
import java.util.ArrayList;
import java.util.List;
public class BowlingLane {
public static final int LAST_FRAME = 10;
protected Frame currentFrame;
protected List<Frame> frames = new ArrayList<Frame>();
public BowlingLane() {
for (int i = 0; i < LAST_FRAME - 1; i++) {
frames.add(new Frame(frames));
}
frames.add(new LastFrame(frames));
currentFrame = frames.get(0);
}
public int currentFramePosition() {
return currentFrame.index() + 1;
}
public void dropPins(int pinsDropped) {
currentFrame.drop(pinsDropped);
if (!currentFrame.isLastFrame() && currentFrame.isComplete())
nextFrame();
}
private void nextFrame() {
currentFrame = currentFrame.nextFrame();
}
public boolean gameOver() {
return currentFrame.isLastFrame() && currentFrame.isComplete();
}
public String[] pinsDropped(int frameNumber) {
return frames.get(frameNumber - 1).displayPinsDropped();
}
public String score(int frameNumber) {
Frame frame = frames.get(frameNumber - 1);
Throw score = frame.score();
return score.toString();
}
}
|
package bowling;
import java.util.List;
class Frame {
private static final int TOTAL_PINS = 10;
private List<Frame> frames;
protected Throw[] pinsDropped = new Throw[2];
protected int throwsMadeInFrame;
Frame(List<Frame> frames) {
this.frames = frames;
pinsDropped[0] = new Throw();
pinsDropped[1] = new Throw();
}
boolean isFirstFrame() {
return frames.indexOf(this) == 0;
}
boolean isLastFrame() {
return frames.indexOf(this) == frames.size() - 1;
}
Frame nextFrame() {
return frames.get(frames.indexOf(this) + 1);
}
Frame previousFrame() {
return frames.get(frames.indexOf(this) - 1);
}
int index() {
return frames.indexOf(this);
}
String[] displayPinsDropped() {
String[] pinsDroppedAsStrings = new String[pinsDropped.length];
for (int i = 0; i < pinsDropped.length; i++) {
pinsDroppedAsStrings[i] = displayThrow(i, pinsDropped[i]);
}
return pinsDroppedAsStrings;
}
private String displayThrow(int throwIndex, Throw pinsDropped) {
if (pinsDropped.intValue() == TOTAL_PINS) {
return "X";
} else if (isSpare() && throwIndex == 1) {
return "/";
} else {
return pinsDropped.toString();
}
}
void drop(int pinsDropped) {
this.pinsDropped[throwsMadeInFrame++] = new Throw(pinsDropped);
}
int throwsMadeInFrame() {
return throwsMadeInFrame;
}
boolean isComplete() {
return throwsMadeInFrame() == requiredThrowsForFrame();
}
protected int requiredThrowsForFrame() {
if (isStrike()) {
return 1;
} else {
return 2;
}
}
protected boolean isStrike() {
return firstThrowPinsDropped() == TOTAL_PINS;
}
protected boolean isSpare() {
return !isStrike() && firstThrowPinsDropped() + secondThrowPinsDropped() == TOTAL_PINS;
}
private int firstThrowPinsDropped() {
return getThrow(0).intValue();
}
private int secondThrowPinsDropped() {
return getThrow(1).intValue();
}
Throw score() {
Throw scoreForCurrentFrame = scoreCurrentFrame();
if (!isFirstFrame()) {
scoreForCurrentFrame = previousFrame().score().add(scoreForCurrentFrame);
}
return scoreForCurrentFrame;
}
protected Throw scoreCurrentFrame() {
Throw score = null;
if (isSpare()) {
score = new Throw(10).add(nextFrame().firstThrowForScoring());
} else if (isStrike()) {
score = new Throw(10).add(nextFrame().firstThrowForScoring()).add(nextFrame().secondThrowForScoring());
} else {
score = firstThrowForScoring().add(secondThrowForScoring());
}
return score;
}
private Throw firstThrowForScoring() {
return getThrow(0);
}
protected Throw secondThrowForScoring() {
if (isStrike()) {
return nextFrame().firstThrowForScoring();
}
return getThrow(1);
}
protected Throw getThrow(int throwIndex) {
return pinsDropped[throwIndex];
}
}
|
package bowling;
import java.util.List;
class LastFrame extends Frame {
LastFrame(List<Frame> frames) {
super(frames);
pinsDropped = new Throw[3];
pinsDropped[0] = new Throw();
pinsDropped[1] = new Throw();
pinsDropped[2] = new Throw();
}
protected int requiredThrowsForFrame() {
if (isStrike() || isSpare()) {
return 3;
} else {
return 2;
}
}
protected Throw secondThrowForScoring() {
return getThrow(1);
}
protected Throw scoreCurrentFrame() {
if (isSpare() || isStrike()) {
return getThrow(0).add(getThrow(1)).add(getThrow(2));
} else {
return super.scoreCurrentFrame();
}
}
}
|
package bowling;
import java.util.List;
class LastFrame extends Frame {
LastFrame(List<Frame> frames) {
super(frames);
pinsDropped = new Throw[3];
pinsDropped[0] = new Throw();
pinsDropped[1] = new Throw();
pinsDropped[2] = new Throw();
}
protected int requiredThrowsForFrame() {
if (isStrike() || isSpare()) {
return 3;
} else {
return 2;
}
}
protected Throw secondThrowForScoring() {
return getThrow(1);
}
protected Throw scoreCurrentFrame() {
if (isSpare() || isStrike()) {
return getThrow(0).add(getThrow(1)).add(getThrow(2));
} else {
return super.scoreCurrentFrame();
}
}
}
|
package bowling;
class Throw {
private Integer pinsDropped;
Throw() {
}
Throw(int pinsDropped) {
this.pinsDropped = new Integer(pinsDropped);
}
Throw add(Throw anotherScore) {
if (pinsDropped == null || anotherScore.pinsDropped == null) {
return new Throw();
}
return new Throw(pinsDropped.intValue() + anotherScore.pinsDropped.intValue());
}
public String toString() {
if (pinsDropped == null) {
return "";
}
return pinsDropped.toString();
}
int intValue() {
if (pinsDropped == null) {
return 0;
}
return pinsDropped.intValue();
}
}
|