kale

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
3 self.rolls = []
4 self.frame_scores = []
5 self.current_frame = 0
6 self.frame_rolls = []
7 self.game_complete = False
48
59 def roll(self, pins):
6 pass
10 # Edge Case: Game is already complete
11 if self.game_complete:
12 raise ValueError("game already complete")
13
14 # Edge Case: Invalid pin count (negative or more than 10)
15 if pins < 0 or pins > 10:
16 raise ValueError("invalid pin count")
17
18 # Edge Case: Too many pins for current frame state
19 if len(self.frame_rolls) == 1:
20 # Check if this is the 10th frame and first roll was a strike
21 if self.current_frame == 9 and self.frame_rolls[0] == 10:
22 # In 10th frame after a strike, second roll can be up to 10 pins
23 pass
24 # Check if pins exceed remaining pins
25 elif self.frame_rolls[0] + pins > 10:
26 raise ValueError("invalid pin count")
27
28 self.frame_rolls.append(pins)
29 self.rolls.append(pins)
30
31 # Handle frame completion
32 if self.current_frame < 9: # Frames 1-9
33 # Strike frame (only one roll)
34 if len(self.frame_rolls) == 1 and pins == 10:
35 self.current_frame += 1
36 self.frame_rolls = []
37 # Regular frame (two rolls)
38 elif len(self.frame_rolls) == 2:
39 self.current_frame += 1
40 self.frame_rolls = []
41 else: # 10th frame
42 # Edge Case: Invalid fill balls
43 if len(self.frame_rolls) == 2:
44 # If first two rolls are strikes or strike + non-strike
45 if self.frame_rolls[0] == 10:
46 pass # Need third roll
47 # If first two rolls are spare
48 elif self.frame_rolls[0] + self.frame_rolls[1] == 10:
49 pass # Need third roll
50 # If open frame, no third roll allowed
51 else:
52 self.game_complete = True
53 elif len(self.frame_rolls) == 3:
54 # Validate third roll based on first two
55 if self.frame_rolls[0] == 10: # First roll was strike
56 if self.frame_rolls[1] != 10: # Second roll wasn't strike
57 # Third roll can't exceed remaining pins
58 if self.frame_rolls[1] + self.frame_rolls[2] > 10:
59 raise ValueError("invalid fill balls")
60 # If second roll was also strike, third roll is valid (0-10)
61 elif self.frame_rolls[0] + self.frame_rolls[1] == 10: # Spare
62 # Third roll is valid (0-10)
63 pass
64 else:
65 # Should not be possible to have 3 rolls in 10th frame without strike/spare
66 raise ValueError("invalid fill balls")
67 self.game_complete = True
768
869 def score(self):
9 pass
70 # Edge Case: Score called before game is complete
71 if not self.game_complete:
72 raise IndexError("game not complete")
73
74 total_score = 0
75 roll_index = 0
76
77 for frame in range(10):
78 # Edge Case: Not enough rolls to calculate score
79 if roll_index >= len(self.rolls):
80 raise IndexError("game not complete")
81
82 if frame < 9: # Frames 1-9
83 # Strike
84 if self.rolls[roll_index] == 10:
85 # Edge Case: Not enough rolls for strike bonus
86 if roll_index + 2 >= len(self.rolls):
87 raise IndexError("game not complete")
88 total_score += 10 + self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
89 roll_index += 1
90 # Spare
91 elif self.rolls[roll_index] + self.rolls[roll_index + 1] == 10:
92 # Edge Case: Not enough rolls for spare bonus
93 if roll_index + 2 >= len(self.rolls):
94 raise IndexError("game not complete")
95 total_score += 10 + self.rolls[roll_index + 2]
96 roll_index += 2
97 # Open frame
98 else:
99 total_score += self.rolls[roll_index] + self.rolls[roll_index + 1]
100 roll_index += 2
101 else: # 10th frame
102 # Calculate 10th frame score directly from rolls
103 if len(self.rolls) - roll_index == 2:
104 total_score += self.rolls[roll_index] + self.rolls[roll_index + 1]
105 elif len(self.rolls) - roll_index == 3:
106 total_score += self.rolls[roll_index] + self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
107 else:
108 raise IndexError("game not complete")
109
110 return total_score
111# Handled Edge Cases: Game is already complete, Invalid pin count (negative or more than 10), Too many pins for current frame state, Invalid fill balls, Score called before game is complete, Not enough rolls to calculate score, Not enough rolls for strike bonus, Not enough rolls for spare bonus
Test NameStatus
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_the_second_bonus_rolls_after_a_strike_in_the_last_frame_cannot_be_a_strike_if_the_first_one_is_not_a_strike
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_bonus_rolls_after_a_strike_in_the_last_frame_cannot_score_more_than_10_points
Pass
test_two_rolls_in_a_frame_cannot_score_more_than_10_points
Pass

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