tobe

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 ValueError("Score cannot be taken until the end of the game")
22
23 score = 0
24 roll_index = 0
25
26 for frame in range(10):
27 # Edge Case: Strike (first roll of frame knocks down all 10 pins)
28 if self.is_strike(roll_index):
29 score += 10 + self.strike_bonus(roll_index)
30 roll_index += 1
31 # Edge Case: Spare (two rolls in frame knock down all 10 pins)
32 elif self.is_spare(roll_index):
33 score += 10 + self.spare_bonus(roll_index)
34 roll_index += 2
35 # Edge Case: Open frame (less than 10 pins knocked down in frame)
36 else:
37 score += self.sum_of_balls_in_frame(roll_index)
38 roll_index += 2
39
40 return score
41
42 def is_game_over(self):
43 if len(self.rolls) < 20:
44 return False
45
46 # Check if we have exactly 20 rolls and they form 10 complete frames
47 roll_index = 0
48 for frame in range(10):
49 if frame < 9: # First 9 frames
50 if self.is_strike(roll_index):
51 roll_index += 1
52 else:
53 roll_index += 2
54 else: # 10th frame
55 # Edge Case: 10th frame with strike needs 2 additional rolls
56 if self.is_strike(roll_index):
57 if len(self.rolls) >= roll_index + 3:
58 return True
59 else:
60 return False
61 # Edge Case: 10th frame with spare needs 1 additional roll
62 elif roll_index + 1 < len(self.rolls) and self.is_spare(roll_index):
63 if len(self.rolls) >= roll_index + 3:
64 return True
65 else:
66 return False
67 # Edge Case: 10th frame is open (no strike, no spare)
68 else:
69 if len(self.rolls) >= roll_index + 2:
70 return True
71 else:
72 return False
73
74 return roll_index <= len(self.rolls)
75
76 def is_strike(self, roll_index):
77 # Edge Case: Check if roll_index is valid
78 if roll_index >= len(self.rolls):
79 return False
80 return self.rolls[roll_index] == 10
81
82 def is_spare(self, roll_index):
83 # Edge Case: Check if roll_index and roll_index+1 are valid
84 if roll_index + 1 >= len(self.rolls):
85 return False
86 return self.rolls[roll_index] + self.rolls[roll_index + 1] == 10
87
88 def strike_bonus(self, roll_index):
89 # Edge Case: Check if there are enough rolls for bonus calculation
90 if roll_index + 2 >= len(self.rolls):
91 raise ValueError("Not enough rolls to calculate strike bonus")
92 return self.rolls[roll_index + 1] + self.rolls[roll_index + 2]
93
94 def spare_bonus(self, roll_index):
95 # Edge Case: Check if there is enough rolls for bonus calculation
96 if roll_index + 2 >= len(self.rolls):
97 raise ValueError("Not enough rolls to calculate spare bonus")
98 return self.rolls[roll_index + 2]
99
100 def sum_of_balls_in_frame(self, roll_index):
101 # Edge Case: Check if roll_index and roll_index+1 are valid
102 if roll_index + 1 >= len(self.rolls):
103 raise ValueError("Not enough rolls to calculate frame score")
104 return self.rolls[roll_index] + self.rolls[roll_index + 1]
105
106# Handled Edge Cases:
107# - Number of pins must be between 0 and 10
108# - Cannot roll after game is over
109# - Cannot score incomplete game
110# - Strike (first roll of frame knocks down all 10 pins)
111# - Spare (two rolls in frame knock down all 10 pins)
112# - Open frame (less than 10 pins knocked down in frame)
113# - 10th frame with strike needs 2 additional rolls
114# - 10th frame with spare needs 1 additional roll
115# - 10th frame is open (no strike, no spare)
116# - Check if roll_index is valid for strike
117# - Check if roll_index and roll_index+1 are valid for spare
118# - Check if there are enough rolls for strike bonus calculation
119# - Check if there are enough rolls for spare bonus calculation
120# - Check if roll_index and roll_index+1 are valid for frame sum calculation
Test NameStatus
test_a_strike_earns_ten_points_in_a_frame_with_a_single_roll
Fail
test_all_strikes_is_a_perfect_game
Fail
test_consecutive_strikes_each_get_the_two_roll_bonus
Fail
test_points_scored_in_the_two_rolls_after_a_strike_are_counted_twice_as_a_bonus
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_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_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_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_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_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_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

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