couple

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
4
3 """
4 Initialize a new bowling game.
5 """
6 self.rolls = []
7 self.frames = []
8 self.current_frame_rolls = []
9
510 def roll(self, pins):
6 pass
7
11 """
12 Record a roll in the game.
13
14 Args:
15 pins (int): Number of pins knocked down in this roll
16
17 Raises:
18 ValueError: If pins is negative or greater than 10
19 ValueError: If trying to roll after the game is over
20 """
21 # Edge Case: Invalid pin count (negative or more than 10)
22 if pins < 0 or pins > 10:
23 raise ValueError("Pins must be between 0 and 10")
24
25 # Edge Case: Game already completed
26 if self._is_game_complete():
27 raise ValueError("Game is already complete")
28
29 # Edge Case: Invalid roll in frame (more than 10 pins in a frame before 10th frame)
30 if len(self.frames) < 9: # Only apply this validation to regular frames 1-9
31 if self.current_frame_rolls and (sum(self.current_frame_rolls) + pins) > 10:
32 raise ValueError("Cannot knock down more pins than available")
33
34 self.current_frame_rolls.append(pins)
35
36 # Check if frame is complete
37 if len(self.frames) < 9: # Regular frames 1-9
38 # Strike in regular frame
39 if len(self.current_frame_rolls) == 1 and pins == 10:
40 self.frames.append(list(self.current_frame_rolls))
41 self.current_frame_rolls = []
42 # Regular frame completion (2 rolls or all pins down)
43 elif len(self.current_frame_rolls) == 2 or sum(self.current_frame_rolls) == 10:
44 self.frames.append(list(self.current_frame_rolls))
45 self.current_frame_rolls = []
46 elif len(self.frames) == 9: # 10th frame (including fill balls)
47 # For the 10th frame, we keep all rolls (including fill balls) in current_frame_rolls
48 # until we've completed all required rolls
49 if self._is_tenth_frame_complete():
50 # When the 10th frame is truly complete (with fill balls), move it to frames
51 self.frames.append(list(self.current_frame_rolls))
52 self.current_frame_rolls = []
53 # If len(self.frames) == 10, we've already completed the 10th frame and game should be over
54
55 def _is_tenth_frame_complete(self):
56 """
57 Check if the 10th frame is complete.
58
59 Returns:
60 bool: True if the 10th frame is complete, False otherwise
61 """
62 if len(self.current_frame_rolls) < 2:
63 return False
64
65 # If first two rolls are a strike or spare, need a third roll
66 if self.current_frame_rolls[0] == 10 or sum(self.current_frame_rolls[:2]) == 10:
67 return len(self.current_frame_rolls) == 3
68 else:
69 # Open frame in 10th, only 2 rolls needed
70 return len(self.current_frame_rolls) == 2
71
72 def _is_game_complete(self):
73 """
74 Check if the game is complete.
75
76 Returns:
77 bool: True if the game is complete, False otherwise
78 """
79 # If we have 10 complete frames and no rolls in progress, the game is complete
80 if len(self.frames) == 10 and len(self.current_frame_rolls) == 0:
81 return True
82
83 # If we have 9 frames and we're working on the 10th frame
84 if len(self.frames) == 9 and self.current_frame_rolls:
85 # Check if the 10th frame (including any required fill balls) is complete
86 tenth_frame_rolls = self.current_frame_rolls
87 if len(tenth_frame_rolls) >= 2:
88 # If first two rolls are a strike or spare, need a third roll (fill ball)
89 if tenth_frame_rolls[0] == 10 or sum(tenth_frame_rolls[:2]) == 10:
90 return len(tenth_frame_rolls) == 3
91 else:
92 # Open frame in 10th, only 2 rolls needed
93 return len(tenth_frame_rolls) == 2
94 return False
95
96 return False
97
898 def score(self):
9 pass
99 """
100 Calculate the total score for the game.
101
102 Returns:
103 int: The total score for the game
104
105 Raises:
106 ValueError: If the game is not yet complete
107 """
108 # Edge Case: Game not complete
109 if not self._is_game_complete():
110 raise ValueError("Game is not yet complete")
111
112 total_score = 0
113
114 # Score all 10 frames
115 for i in range(10):
116 frame = self.frames[i]
117 frame_score = sum(frame)
118
119 # Strike (first 9 frames)
120 if i < 9 and len(frame) == 1 and frame[0] == 10:
121 # Add next two rolls
122 if i + 1 < len(self.frames):
123 next_frame = self.frames[i + 1]
124 if len(next_frame) >= 1:
125 frame_score += next_frame[0]
126 if len(next_frame) >= 2:
127 frame_score += next_frame[1]
128 elif len(next_frame) == 1 and i + 2 < len(self.frames): # Next frame was also a strike
129 frame_score += self.frames[i + 2][0]
130 # Spare (first 9 frames)
131 elif i < 9 and len(frame) == 2 and sum(frame) == 10:
132 # Add next roll
133 if i + 1 < len(self.frames):
134 frame_score += self.frames[i + 1][0]
135
136 total_score += frame_score
137
138 return total_score
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_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
test_two_rolls_in_a_frame_cannot_score_more_than_10_points
Pass

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