001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package eg.bowling;
004:
005: public class BowlingGame implements Bowling {
006: private static final int FIRST_BALL_IN_FRAME = 0;
007: private static final int SECOND_BALL_IN_FRAME = 1;
008: private static final int GAME_OVER = 2;
009: private static final int BALL_AFTER_SPARE = 3;
010: private static final int BALL_AFTER_TENTH_FRAME_SPARE = 4;
011: private static final int BALL_AFTER_FIRST_STRIKE = 5;
012: private static final int BALL_AFTER_SECOND_STRIKE = 6;
013:
014: private int currentFrame = 1;
015: private int currentBall = 1;
016: private int scoreableFrame = 0;
017: private boolean gameOver = false;
018:
019: private int state = FIRST_BALL_IN_FRAME;
020: private final BowlingScorer bowlingScorer = new BowlingScorer();
021:
022: private void changeState() {
023: switch (state) {
024: case FIRST_BALL_IN_FRAME:
025: firstBallInFrame();
026: break;
027:
028: case SECOND_BALL_IN_FRAME:
029: secondBallInFrame();
030: break;
031:
032: case BALL_AFTER_SPARE:
033: ballAfterSpare();
034: break;
035:
036: case BALL_AFTER_TENTH_FRAME_SPARE:
037: endGame();
038: break;
039:
040: case BALL_AFTER_FIRST_STRIKE:
041: ballAfterFirstStrike();
042: break;
043:
044: case BALL_AFTER_SECOND_STRIKE:
045: ballAfterSecondStrike();
046: break;
047: }
048: }
049:
050: private void firstBallInFrame() {
051: if (bowlingScorer.lastRollWasStrike()) {
052: state = BALL_AFTER_FIRST_STRIKE;
053: incrementFrame();
054: } else {
055: state = SECOND_BALL_IN_FRAME;
056: currentBall = 2;
057: }
058: }
059:
060: private void secondBallInFrame() {
061: if (bowlingScorer.lastRollWasSpare() && currentFrame == 10) {
062: state = BALL_AFTER_TENTH_FRAME_SPARE;
063: currentBall = 3;
064: } else if (bowlingScorer.lastRollWasSpare()) {
065: state = BALL_AFTER_SPARE;
066: incrementFrame();
067: } else if (currentFrame == 10) {
068: endGame();
069: } else {
070: state = FIRST_BALL_IN_FRAME;
071: scoreableFrame = currentFrame;
072: incrementFrame();
073: }
074: }
075:
076: private void ballAfterSpare() {
077: if (bowlingScorer.lastRollWasStrike()) {
078: state = BALL_AFTER_FIRST_STRIKE;
079: scoreableFrame++;
080: incrementFrame();
081: } else {
082: state = SECOND_BALL_IN_FRAME;
083: currentBall = 2;
084: scoreableFrame++;
085: }
086: }
087:
088: private void ballAfterFirstStrike() {
089: if (bowlingScorer.lastRollWasStrike()) {
090: state = BALL_AFTER_SECOND_STRIKE;
091: incrementFrame();
092: } else {
093: state = SECOND_BALL_IN_FRAME;
094: currentBall = 2;
095: }
096: }
097:
098: private void ballAfterSecondStrike() {
099: if (bowlingScorer.lastRollWasStrike() && currentFrame == 10
100: && currentBall == 3) {
101: endGame();
102: } else if (bowlingScorer.lastRollWasStrike()) {
103: incrementFrame();
104: scoreableFrame++;
105: } else {
106: state = SECOND_BALL_IN_FRAME;
107: currentBall = 2;
108: scoreableFrame++;
109: }
110: }
111:
112: private void endGame() {
113: state = GAME_OVER;
114: currentBall = 0;
115: scoreableFrame = 10;
116: gameOver = true;
117: }
118:
119: private void incrementFrame() {
120: if (currentFrame < 10) {
121: currentFrame++;
122: currentBall = 1;
123: } else
124: currentBall++;
125: }
126:
127: public int currentFrame() {
128: return currentFrame;
129: }
130:
131: public int currentBall() {
132: return currentBall;
133: }
134:
135: public int scoreableFrame() {
136: return scoreableFrame;
137: }
138:
139: public boolean validGame() {
140: return true;
141: }
142:
143: public boolean gameOver() {
144: return currentFrame == 10 && currentBall == 0;
145: }
146:
147: public boolean isGameOver() {
148: return gameOver;
149: }
150:
151: public void roll(int pins) {
152: bowlingScorer.roll(pins);
153: changeState();
154: }
155:
156: public int score(int frame) {
157: return bowlingScorer.score(frame);
158: }
159: }
|