couple

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
4
3 """
4 Initialize a new bowling game.
5 """
6 self.rolls = []
7 self.current_frame = 1
8 self.frame_rolls = []
9 self.frames = []
10 self.game_over = False
11
512 def roll(self, pins):
6 pass
7
13 """
14 Record a roll in the game.
15
16 Args:
17 pins (int): Number of pins knocked down in this roll.
18
19 Raises:
20 ValueError: If the number of pins is invalid or game is already over.
21 """
22 # Edge Case: Game is already over
23 if self.game_over:
24 raise ValueError("game is already over")
25
26 # Edge Case: Invalid number of pins (negative or more than 10)
27 if pins < 0 or pins > 10:
28 raise ValueError("invalid number of pins")
29
30 # Edge Case: Too many pins in a frame
31 if len(self.frame_rolls) == 1 and (self.frame_rolls[0] + pins) > 10 and self.current_frame < 10:
32 raise ValueError("invalid number of pins")
33
34 self.frame_rolls.append(pins)
35 self.rolls.append(pins)
36
37 # Handle regular frames (1-9)
38 if self.current_frame < 10:
39 # Strike case
40 if len(self.frame_rolls) == 1 and pins == 10:
41 self.frames.append(self.frame_rolls[:])
42 self.frame_rolls = []
43 self.current_frame += 1
44 # Two rolls completed
45 elif len(self.frame_rolls) == 2:
46 self.frames.append(self.frame_rolls[:])
47 self.frame_rolls = []
48 self.current_frame += 1
49 # Handle 10th frame
50 else:
51 # First roll is a strike
52 if len(self.frame_rolls) == 1 and pins == 10:
53 # Just continue to next rolls
54 pass
55 # Second roll completes a spare or strike
56 elif len(self.frame_rolls) == 2:
57 # If first two rolls sum to 10, need a third roll
58 if sum(self.frame_rolls) >= 10:
59 # Continue to third roll
60 pass
61 else:
62 # Frame is complete (open frame)
63 self.frames.append(self.frame_rolls[:])
64 self.game_over = True
65 # Third roll
66 elif len(self.frame_rolls) == 3:
67 # Edge Case: Invalid fill balls
68 # If first two rolls are not strikes or spare, third roll shouldn't happen
69 if self.frame_rolls[0] != 10 and sum(self.frame_rolls[:2]) < 10:
70 raise ValueError("invalid fill balls")
71 # If second roll is not a strike and first two don't make 10, invalid
72 if self.frame_rolls[0] == 10 and self.frame_rolls[1] != 10 and sum(self.frame_rolls[:2]) < 10:
73 if len(self.frame_rolls) > 2:
74 raise ValueError("invalid fill balls")
75 self.frames.append(self.frame_rolls[:])
76 self.game_over = True
77
878 def score(self):
9 pass
79 """
80 Calculate the total score for the game.
81
82 Returns:
83 int: The total score of the game.
84
85 Raises:
86 ValueError: If the game is not yet complete.
87 """
88 # Edge Case: Game is not complete
89 if not self.game_over and (len(self.frames) < 10 or (len(self.frames) == 10 and len(self.frame_rolls) > 0)):
90 raise ValueError("game is not yet complete")
91
92 total_score = 0
93 roll_index = 0
94
95 # Score first 9 frames
96 for frame_index in range(9):
97 # Edge Case: Not enough frames
98 if frame_index >= len(self.frames):
99 raise ValueError("game is not yet complete")
100
101 frame = self.frames[frame_index]
102
103 # Strike
104 if len(frame) == 1 and frame[0] == 10:
105 total_score += 10
106 # Add next two rolls
107 # Edge Case: Not enough rolls for strike bonus
108 if frame_index == len(self.frames) - 1: # Last frame in frames
109 if len(frame) < 3: # Not enough rolls in 10th frame
110 raise ValueError("game is not yet complete")
111 total_score += frame[1] + frame[2]
112 else:
113 next_frame = self.frames[frame_index + 1]
114 total_score += next_frame[0]
115 if len(next_frame) > 1:
116 total_score += next_frame[1]
117 else: # Next frame is also a strike
118 if frame_index + 1 < len(self.frames) - 1:
119 total_score += self.frames[frame_index + 2][0]
120 else:
121 # Edge Case: Not enough rolls for double strike bonus
122 raise ValueError("game is not yet complete")
123 # Spare
124 elif len(frame) == 2 and sum(frame) == 10:
125 total_score += 10
126 # Add next roll
127 if frame_index == len(self.frames) - 1: # Last frame
128 if len(frame) < 3:
129 raise ValueError("game is not yet complete")
130 total_score += frame[2]
131 else:
132 total_score += self.frames[frame_index + 1][0]
133 # Open frame
134 else:
135 total_score += sum(frame)
136
137 # Score 10th frame
138 # Edge Case: Missing 10th frame
139 if len(self.frames) < 10:
140 raise ValueError("game is not yet complete")
141
142 tenth_frame = self.frames[9]
143 total_score += sum(tenth_frame)
144
145 return total_score
146
147 # Handled Edge Cases: Game already over, invalid pins, too many pins in frame, invalid fill balls, game not complete, missing frames, not enough rolls for bonuses
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.