chris

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
511 def roll(self, pins):
6 pass
7
12 """
13 Record a roll in the game.
14
15 Args:
16 pins (int): Number of pins knocked down in this roll
17
18 Raises:
19 ValueError: If pins is negative or greater than 10
20 ValueError: If game is already over
21 """
22 # Edge Case: Invalid number of pins
23 if pins < 0:
24 raise ValueError("Negative roll is invalid")
25
26 # Edge Case: More than 10 pins in a roll
27 if pins > 10:
28 raise ValueError("Pin count exceeds pins on the lane")
29
30 # Edge Case: Game already completed
31 if len(self.frames) == 10 and (len(self.frames[9]) == 2 or
32 (len(self.frames[9]) == 1 and self.frames[9][0] != 10)):
33 # Check if we still need fill balls
34 tenth_frame = self.frames[9]
35 if len(tenth_frame) == 2 and tenth_frame[0] == 10: # Strike in 10th frame
36 if len(self.frame_rolls) < 2: # Need 2 fill balls
37 self.frame_rolls.append(pins)
38 if len(self.frame_rolls) == 2:
39 self.frames.append(self.frame_rolls)
40 return
41 else:
42 raise ValueError("Cannot roll after game is over")
43 elif len(tenth_frame) == 2 and sum(tenth_frame) == 10: # Spare in 10th frame
44 if len(self.frame_rolls) < 1: # Need 1 fill ball
45 self.frame_rolls.append(pins)
46 self.frames.append(self.frame_rolls)
47 return
48 else:
49 raise ValueError("Cannot roll after game is over")
50 else:
51 raise ValueError("Cannot roll after game is over")
52
53 # Edge Case: Game already completed (no fill balls needed)
54 if len(self.frames) == 10:
55 raise ValueError("Cannot roll after game is over")
56
57 self.frame_rolls.append(pins)
58
59 # Handle frame completion
60 if len(self.frame_rolls) == 2 or self.frame_rolls[0] == 10:
61 # Edge Case: Invalid frame (e.g., more than 10 pins in two rolls, except in 10th frame)
62 if len(self.frame_rolls) == 2 and self.frame_rolls[0] != 10 and sum(self.frame_rolls) > 10:
63 raise ValueError("Pin count exceeds pins on the lane")
64
65 self.frames.append(self.frame_rolls)
66 self.current_frame += 1
67 self.frame_rolls = []
68
869 def score(self):
9 pass
70 """
71 Calculate the total score for the game.
72
73 Returns:
74 int: The total score for the game
75
76 Raises:
77 ValueError: If the game is not yet complete
78 """
79 # Edge Case: Game not complete
80 if len(self.frames) < 10:
81 raise ValueError("Score cannot be taken until the end of the game")
82
83 # Edge Case: 10th frame is incomplete
84 tenth_frame = self.frames[9]
85 if len(tenth_frame) == 1 and tenth_frame[0] != 10:
86 raise ValueError("Score cannot be taken until the end of the game")
87 if len(tenth_frame) == 2 and tenth_frame[0] == 10 and len(self.frames) < 11:
88 raise ValueError("Score cannot be taken until the end of the game")
89 if len(tenth_frame) == 2 and sum(tenth_frame) == 10 and len(self.frames) < 11:
90 raise ValueError("Score cannot be taken until the end of the game")
91
92 total_score = 0
93
94 # Score first 9 frames
95 for i in range(9):
96 frame = self.frames[i]
97 frame_score = sum(frame)
98
99 if frame[0] == 10: # Strike
100 # Add next two rolls
101 if i+1 < len(self.frames):
102 next_frame = self.frames[i+1]
103 if len(next_frame) >= 2:
104 frame_score += next_frame[0] + next_frame[1]
105 elif len(next_frame) == 1 and i+2 < len(self.frames):
106 # Next frame is also a strike
107 frame_score += next_frame[0] + self.frames[i+2][0]
108 elif frame_score == 10: # Spare
109 # Add next roll
110 if i+1 < len(self.frames):
111 frame_score += self.frames[i+1][0]
112
113 total_score += frame_score
114
115 # Score 10th frame
116 tenth_frame_score = sum(tenth_frame)
117 if len(tenth_frame) > 2: # Fill balls were added
118 # Add fill ball values
119 if len(tenth_frame) == 3:
120 tenth_frame_score = sum(tenth_frame)
121
122 total_score += tenth_frame_score
123
124 return total_score
125
126 # Handled Edge Cases: Invalid number of pins, more than 10 pins in a roll, game already completed, invalid frame, game not complete, 10th frame incomplete
127
128# Handled Edge Cases: Invalid initialization
129# Handled Edge Cases: Invalid number of pins, more than 10 pins in a roll, game already completed, invalid frame, game not complete, 10th frame incomplete
Test NameStatus
test_a_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once
Fail
test_a_strike_in_the_last_frame_gets_a_two_roll_bonus_that_is_counted_once
Fail
test_a_strike_with_the_one_roll_bonus_after_a_spare_in_the_last_frame_does_not_get_a_bonus
Fail
test_all_strikes_is_a_perfect_game
Fail
test_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Fail
test_both_bonus_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Fail
test_cannot_roll_after_bonus_roll_for_spare
Fail
test_cannot_roll_after_bonus_rolls_for_strike
Fail
test_last_two_strikes_followed_by_only_last_bonus_with_non_strike_points
Fail
test_rolling_a_spare_with_the_two_roll_bonus_does_not_get_a_bonus_roll
Fail
test_second_bonus_roll_after_a_strike_in_the_last_frame_cannot_score_more_than_10_points
Fail
test_strikes_with_the_two_roll_bonus_do_not_get_bonus_rolls
Fail
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_can_score_more_than_10_points_if_one_is_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_strike_earns_ten_points_in_a_frame_with_a_single_roll
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_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_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_rolls_cannot_score_negative_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_two_rolls_in_a_frame_cannot_score_more_than_10_points
Pass

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