awesome

Finished
11class BowlingGame:
22 def __init__(self):
3 pass
4
3 self.rolls = []
4 self.current_roll = 0
5
56 def roll(self, pins):
6 pass
7
7 # Edge Case: Number of pins must be between 0 and 10
8 if pins < 0 or pins > 10:
9 raise ValueError("Pins must be between 0 and 10")
10
11 # Edge Case: Cannot roll after game is over
12 if self.is_game_over():
13 raise ValueError("Cannot roll after game is over")
14
15 self.rolls.append(pins)
16 self.current_roll += 1
17
818 def score(self):
9 pass
19 # Edge Case: Cannot score incomplete game
20 if not self.is_game_over():
21 raise IndexError("Score cannot be taken until the end of the game")
22
23 total_score = 0
24 roll_index = 0
25
26 for frame in range(10):
27 # Edge Case: Invalid frame state
28 if roll_index >= len(self.rolls):
29 raise ValueError("Invalid game state")
30
31 if self.is_strike(roll_index): # Strike
32 # Edge Case: Incomplete strike frame
33 if roll_index + 2 >= len(self.rolls):
34 raise ValueError("Invalid game state")
35
36 total_score += 10 + self.strike_bonus(roll_index)
37 roll_index += 1
38 elif self.is_spare(roll_index): # Spare
39 # Edge Case: Incomplete spare frame
40 if roll_index + 2 >= len(self.rolls):
41 raise ValueError("Invalid game state")
42
43 total_score += 10 + self.spare_bonus(roll_index)
44 roll_index += 2
45 else: # Open frame
46 # Edge Case: Incomplete open frame
47 if roll_index + 1 >= len(self.rolls):
48 raise ValueError("Invalid game state")
49
50 frame_score = self.rolls[roll_index] + self.rolls[roll_index + 1]
51 # Edge Case: Frame score cannot exceed 10 in open frame
52 if frame_score > 10:
53 raise ValueError("Invalid frame score")
54
55 total_score += frame_score
56 roll_index += 2
57
58 return total_score
59
60 def is_strike(self, roll_index):
61 return self.rolls[roll_index] == 10
62
63 def is_spare(self, roll_index):
64 return self.rolls[roll_index] + self.rolls[roll_index + 1] == 10
65
66 def strike_bonus(self, roll_index):
67 return self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
68
69 def spare_bonus(self, roll_index):
70 return self.rolls[roll_index + 2]
71
72 def is_game_over(self):
73 if len(self.rolls) < 12: # Minimum rolls needed
74 return False
75
76 # Check if we have exactly 10 frames worth of rolls
77 roll_index = 0
78 frame_count = 0
79
80 while frame_count < 10 and roll_index < len(self.rolls):
81 if self.is_strike(roll_index):
82 roll_index += 1
83 else:
84 roll_index += 2
85 frame_count += 1
86
87 # If we've processed exactly 10 frames
88 if frame_count == 10:
89 # Edge Case: Tenth frame was a strike or spare, need to check fill balls
90 if roll_index < len(self.rolls):
91 # If tenth frame was a strike
92 if self.rolls[roll_index-1] == 10:
93 # Need exactly two more rolls
94 return roll_index + 1 == len(self.rolls)
95 # If tenth frame was open
96 else:
97 return roll_index == len(self.rolls)
98 else:
99 return True
100
101 return False
102
103 # Handled Edge Cases: Pins out of range, rolling after game over, scoring incomplete game, incomplete frames, invalid frame scores
Test NameStatus
test_a_spare_followed_by_zeros_is_worth_ten_points
Fail
test_a_spare_in_the_last_frame_gets_a_one_roll_bonus_that_is_counted_once
Fail
test_a_strike_earns_ten_points_in_a_frame_with_a_single_roll
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_roll_for_a_spare_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_cannot_roll_if_game_already_has_ten_frames
Fail
test_consecutive_spares_each_get_a_one_roll_bonus
Fail
test_consecutive_strikes_each_get_the_two_roll_bonus
Fail
test_last_two_strikes_followed_by_only_last_bonus_with_non_strike_points
Fail
test_points_scored_in_the_roll_after_a_spare_are_counted_twice
Fail
test_points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus
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_should_be_able_to_score_a_game_with_all_zeros
Fail
test_should_be_able_to_score_a_game_with_no_strikes_or_spares
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_two_rolls_in_a_frame_cannot_score_more_than_10_points
Fail
test_a_roll_cannot_score_more_than_10_points
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_rolls_for_a_strike_in_the_last_frame_must_be_rolled_before_score_can_be_calculated
Pass
test_rolls_cannot_score_negative_points
Pass

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