Alone

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
4
3 """
4 Initialize a new bowling game.
5 """
6 self.rolls = []
7 self.current_roll = 0
8
59 def roll(self, pins):
6 pass
7
10 """
11 Record a roll in the game.
12
13 Args:
14 pins (int): Number of pins knocked down in this roll.
15
16 Raises:
17 ValueError: If the number of pins is invalid.
18 """
19 # Edge Case: Invalid number of pins (negative or over 10)
20 if pins < 0 or pins > 10:
21 raise ValueError("Pins must be between 0 and 10")
22
23 # Edge Case: Can't roll if game is over
24 if self.is_game_over():
25 raise ValueError("Game is already complete")
26
27 # Add the roll to our list
28 self.rolls.append(pins)
29
830 def score(self):
9 pass
31 """
32 Calculate the total score for the game.
33
34 Returns:
35 int: The total score of the game.
36
37 Raises:
38 ValueError: If the game is not yet complete.
39 """
40 # Edge Case: Game is not complete
41 if not self.is_game_over():
42 raise ValueError("Game is not yet complete")
43
44 total_score = 0
45 roll_index = 0
46
47 # Score the first 9 frames
48 for frame in range(9):
49 # Check if it's a strike
50 if self.rolls[roll_index] == 10: # Strike
51 total_score += 10 + self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
52 roll_index += 1
53 # Check if it's a spare
54 elif self.rolls[roll_index] + self.rolls[roll_index + 1] == 10: # Spare
55 total_score += 10 + self.rolls[roll_index + 2]
56 roll_index += 2
57 # Open frame
58 else:
59 total_score += self.rolls[roll_index] + self.rolls[roll_index + 1]
60 roll_index += 2
61
62 # Score the 10th frame (no bonus balls counted here)
63 total_score += self.rolls[roll_index] + self.rolls[roll_index + 1]
64 # Add third roll if it exists (for strikes/spares in 10th frame)
65 if len(self.rolls) > roll_index + 2:
66 total_score += self.rolls[roll_index + 2]
67
68 return total_score
69
70 def is_game_over(self):
71 """
72 Check if the game is over.
73
74 Returns:
75 bool: True if the game is over, False otherwise.
76 """
77 # A bowling game is complete when we have 10 frames worth of rolls
78 # Frames 1-9: Each frame has 1 or 2 rolls (2 if open frame, 1 if strike)
79 # Frame 10: 2 or 3 rolls depending on whether there were strikes/spares
80
81 # Need at least 10 rolls (10 strikes) to complete a game
82 if len(self.rolls) < 10:
83 return False
84
85 # Count frames completed
86 roll_index = 0
87 frames_completed = 0
88
89 # Count frames 1-9
90 while frames_completed < 9 and roll_index < len(self.rolls):
91 # If it's a strike (10 pins on first roll)
92 if self.rolls[roll_index] == 10:
93 roll_index += 1 # Strike uses 1 roll
94 else:
95 # Not a strike, so use 2 rolls for this frame
96 # But first check if we have 2 rolls available
97 if roll_index + 1 >= len(self.rolls):
98 # Not enough rolls to complete this frame
99 break
100 roll_index += 2
101 frames_completed += 1
102
103 # If we haven't completed 9 frames, game is not over
104 if frames_completed < 9:
105 return False
106
107 # Now check the 10th frame
108 # At this point, roll_index points to the start of the 10th frame
109 # We need to determine if the 10th frame is complete
110
111 # If we don't have any rolls for the 10th frame yet
112 if roll_index >= len(self.rolls):
113 return False
114
115 # Check first roll of 10th frame
116 tenth_frame_first = self.rolls[roll_index]
117 roll_index += 1
118
119 # If first roll was a strike
120 if tenth_frame_first == 10:
121 # Need at least 2 more rolls for bonus balls
122 if roll_index + 1 >= len(self.rolls):
123 return False
124 # If second roll was also a strike
125 if self.rolls[roll_index] == 10:
126 # Need a third bonus roll
127 if roll_index + 1 >= len(self.rolls):
128 return False
129 else:
130 # Second roll wasn't a strike, but we still need the third roll for bonus
131 if roll_index + 1 >= len(self.rolls):
132 return False
133 else:
134 # First roll wasn't a strike
135 # Need a second roll
136 if roll_index >= len(self.rolls):
137 return False
138
139 tenth_frame_second = self.rolls[roll_index]
140 roll_index += 1
141
142 # If the first two rolls make a spare (total 10)
143 if tenth_frame_first + tenth_frame_second == 10:
144 # Need a bonus roll
145 if roll_index >= len(self.rolls):
146 return False
147
148 # If we get here, the 10th frame is complete
149 return True
150
151 # Handled Edge Cases: Invalid pins count (negative), invalid pins count (over 10),
152 # game over state, 10th frame rules, strike/spare validation, incomplete game scoring
Test NameStatus
test_the_second_bonus_rolls_after_a_strike_in_the_last_frame_cannot_be_a_strike_if_the_first_one_is_not_a_strike
Fail
test_two_bonus_rolls_after_a_strike_in_the_last_frame_cannot_score_more_than_10_points
Fail
test_two_rolls_in_a_frame_cannot_score_more_than_10_points
Fail
test_a_roll_cannot_score_more_than_10_points
Pass
test_a_spare_followed_by_zeros_is_worth_ten_points
Pass
test_a_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once
Pass
test_a_strike_earns_ten_points_in_a_frame_with_a_single_roll
Pass
test_a_strike_in_the_last_frame_gets_a_two_roll_bonus_that_is_counted_once
Pass
test_a_strike_with_the_one_roll_bonus_after_a_spare_in_the_last_frame_does_not_get_a_bonus
Pass
test_all_strikes_is_a_perfect_game
Pass
test_an_incomplete_game_cannot_be_scored
Pass
test_an_unstarted_game_cannot_be_scored
Pass
test_bonus_roll_after_a_strike_in_the_last_frame_cannot_score_more_than_10_points
Pass
test_bonus_roll_for_a_spare_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Pass
test_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Pass
test_both_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Pass
test_cannot_roll_after_bonus_roll_for_spare
Pass
test_cannot_roll_after_bonus_rolls_for_strike
Pass
test_cannot_roll_if_game_already_has_ten_frames
Pass
test_consecutive_spares_each_get_a_one_roll_bonus
Pass
test_consecutive_strikes_each_get_the_two_roll_bonus
Pass
test_last_two_strikes_followed_by_only_last_bonus_with_non_strike_points
Pass
test_points_scored_in_the_roll_after_a_spare_are_counted_twice
Pass
test_points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus
Pass
test_rolling_a_spare_with_the_two_roll_bonus_does_not_get_a_bonus_roll
Pass
test_rolls_cannot_score_negative_points
Pass
test_second_bonus_roll_after_a_strike_in_the_last_frame_cannot_score_more_than_10_points
Pass
test_should_be_able_to_score_a_game_with_all_zeros
Pass
test_should_be_able_to_score_a_game_with_no_strikes_or_spares
Pass
test_strikes_with_the_two_roll_bonus_do_not_get_bonus_rolls
Pass
test_two_bonus_rolls_after_a_strike_in_the_last_frame_can_score_more_than_10_points_if_one_is_a_strike
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.