1+ import java .util .ArrayList ;
2+ import java .util .List ;
3+
4+ public class BowlingGame {
5+ private static final int NUMBER_OF_FRAMES = 10 ;
6+ private static final int MAXIMUM_FRAME_SCORE = 10 ;
7+ private List <Integer > rolls = new ArrayList <Integer >();
8+
9+ public void roll (int pins ) {
10+ rolls .add (pins );
11+ }
12+
13+ public int score () {
14+ int score = 0 ;
15+ int frameIndex = 0 ;
16+
17+ for (int i = 1 ; i <= NUMBER_OF_FRAMES ; i ++) {
18+ if (rolls .size () <= frameIndex ) {
19+ throw new IllegalStateException ("Score cannot be taken until the end of the game" );
20+ }
21+
22+ if (isStrike (frameIndex )) {
23+ if (rolls .size () <= frameIndex + 2 ) {
24+ throw new IllegalStateException ("Score cannot be taken until the end of the game" );
25+ }
26+
27+ int strikeBonus = strikeBonus (frameIndex );
28+ if (strikeBonus > MAXIMUM_FRAME_SCORE && !isStrike (frameIndex + 1 )) {
29+ throw new IllegalStateException ("Pin count exceeds pins on the lane" );
30+ }
31+
32+ score += 10 + strikeBonus ;
33+ frameIndex += i == NUMBER_OF_FRAMES ? 3 : 1 ;
34+ } else if (isSpare (frameIndex )) {
35+ if (rolls .size () <= frameIndex + 2 ) {
36+ throw new IllegalStateException ("Score cannot be taken until the end of the game" );
37+ }
38+
39+ score += 10 + spareBonus (frameIndex );
40+ frameIndex += i == NUMBER_OF_FRAMES ? 3 : 2 ;
41+ } else {
42+ int frameScore = frameScore (frameIndex );
43+ if (frameScore < 0 ) {
44+ throw new IllegalStateException ("Negative roll is invalid" );
45+ } else if (frameScore > 10 ) {
46+ throw new IllegalStateException ("Pin count exceeds pins on the lane" );
47+ }
48+
49+ score += frameScore ;
50+ frameIndex += 2 ;
51+ }
52+ }
53+
54+ if (!correctNumberOfRolls (frameIndex )) {
55+ throw new IllegalStateException ("Cannot roll after game is over" );
56+ }
57+
58+ return score ;
59+ }
60+
61+ private boolean correctNumberOfRolls (int frameIndex ) {
62+ return frameIndex == rolls .size ();
63+ }
64+
65+ private boolean isStrike (int frameIndex ) {
66+ return rolls .get (frameIndex ) == MAXIMUM_FRAME_SCORE ;
67+ }
68+
69+ private boolean isSpare (int frameIndex ) {
70+ return rolls .get (frameIndex ) + rolls .get (frameIndex + 1 ) == MAXIMUM_FRAME_SCORE ;
71+ }
72+
73+ private int strikeBonus (int frameIndex ) {
74+ return rolls .get (frameIndex + 1 ) + rolls .get (frameIndex + 2 );
75+ }
76+
77+ private int spareBonus (int frameIndex ) {
78+ return rolls .get (frameIndex + 2 );
79+ }
80+
81+ private int frameScore (int frameIndex ) {
82+ return rolls .get (frameIndex ) + rolls .get (frameIndex + 1 );
83+ }
84+ }
0 commit comments