hope

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
3 self.rolls = []
4 self.current_frame = 1
5 self.frame_rolls = 0 # Number of rolls in the current frame
6 self.is_finished = False
47
58 def roll(self, pins):
6 pass
7
9 # Edge Case: Game is already finished
10 if self.is_finished:
11 raise ValueError("Cannot roll after game is over")
12
13 # Edge Case: Invalid pin count (negative or more than 10)
14 if pins < 0 or pins > 10:
15 raise ValueError("Pins must be between 0 and 10")
16
17 # Edge Case: Too many pins in a frame (except for special 10th frame cases)
18 if self.frame_rolls == 1 and self.current_frame < 10:
19 # For frames 1-9, check if the sum exceeds 10
20 if self.rolls[-1] + pins > 10:
21 raise ValueError("Cannot knock down more than 10 pins in a frame")
22
23 self.rolls.append(pins)
24
25 # Handle frame progression
26 if self.current_frame < 10:
27 # For frames 1-9
28 if self.frame_rolls == 0:
29 if pins == 10: # Strike
30 self.current_frame += 1
31 self.frame_rolls = 0
32 else:
33 self.frame_rolls = 1
34 else: # Second roll in frame
35 self.current_frame += 1
36 self.frame_rolls = 0
37 else:
38 # For frame 10
39 if self.frame_rolls == 0:
40 if pins == 10: # First roll is a strike
41 self.frame_rolls = 1
42 else:
43 self.frame_rolls = 1
44 elif self.frame_rolls == 1:
45 # Second roll in frame 10
46 # If first was strike or second completes spare
47 if self.rolls[-2] == 10 or (self.rolls[-2] + pins == 10):
48 self.frame_rolls = 2 # Need one more roll
49 else:
50 # Frame 10 is complete with just two rolls
51 self.is_finished = True
52 else: # Third roll in frame 10
53 self.is_finished = True
54
855 def score(self):
9 pass
56 # Edge Case: Game is not yet finished
57 if not self.is_finished:
58 raise ValueError("Game is not yet complete")
59
60 total_score = 0
61 roll_index = 0
62
63 # Score first 9 frames
64 for frame in range(9):
65 # Edge Case: Not enough rolls to calculate score
66 if roll_index >= len(self.rolls):
67 raise ValueError("Not enough rolls to calculate score")
68
69 if self.rolls[roll_index] == 10: # Strike
70 # Edge Case: Not enough subsequent rolls to calculate strike bonus
71 if roll_index + 2 >= len(self.rolls):
72 raise ValueError("Not enough rolls to calculate score")
73 total_score += 10 + self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
74 roll_index += 1
75 else:
76 frame_score = self.rolls[roll_index] + self.rolls[roll_index + 1]
77 if frame_score == 10: # Spare
78 # Edge Case: Not enough subsequent rolls to calculate spare bonus
79 if roll_index + 2 >= len(self.rolls):
80 raise ValueError("Not enough rolls to calculate score")
81 total_score += 10 + self.rolls[roll_index + 2]
82 else: # Open frame
83 total_score += frame_score
84 roll_index += 2
85
86 # Score 10th frame
87 # Edge Case: Not enough rolls for 10th frame
88 if roll_index >= len(self.rolls):
89 raise ValueError("Not enough rolls to calculate score")
90
91 # Add the remaining rolls (could be 2 or 3 depending on strikes/spares)
92 while roll_index < len(self.rolls):
93 total_score += self.rolls[roll_index]
94 roll_index += 1
95
96 return total_score
97
98# Handled Edge Cases: Game already finished, invalid pin count, too many pins in a frame, game not yet finished when scoring, not enough rolls to calculate score, not enough subsequent rolls to calculate strike/spare bonus
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.