| 1 | ||
| 2 | import sys, pytest, collections, collections.abc, urllib3.exceptions, _pytest.pytester, numpy; | |
| 3 | collections.Mapping = collections.abc.Mapping; | |
| 4 | collections.MutableMapping = collections.abc.MutableMapping; | |
| 5 | collections.MutableSet = collections.abc.MutableSet; | |
| 6 | collections.Sequence = collections.abc.Sequence; | |
| 7 | collections.Callable = collections.abc.Callable; | |
| 8 | collections.Iterable = collections.abc.Iterable; | |
| 9 | collections.Iterator = collections.abc.Iterator; | |
| 10 | urllib3.exceptions.SNIMissingWarning = urllib3.exceptions.DependencyWarning; | |
| 11 | pytest.RemovedInPytest4Warning = DeprecationWarning; | |
| 12 | _pytest.pytester.Testdir = _pytest.pytester.Pytester; | |
| 13 | numpy.PINF = numpy.inf; | |
| 14 | numpy.unicode_ = numpy.str_; | |
| 15 | numpy.bytes_ = numpy.bytes_; | |
| 16 | numpy.float_ = numpy.float64; | |
| 17 | numpy.string_ = numpy.bytes_; | |
| 18 | numpy.NaN = numpy.nan; | |
| 19 | ||
| 20 | ||
| 21 | from main import BowlingGame | |
| 22 | import unittest | |
| 23 | ||
| 24 | class ComprehensiveTest(unittest.TestCase): | |
| 25 | def test_complex_game_with_strikes_and_spares(self): | |
| 26 | """Test a complex game with various strike and spare combinations.""" | |
| 27 | game = BowlingGame() | |
| 28 | ||
| 29 | # Frame 1: Strike | |
| 30 | game.roll(10) | |
| 31 | ||
| 32 | # Frame 2: Spare (5+5) | |
| 33 | game.roll(5) | |
| 34 | game.roll(5) | |
| 35 | ||
| 36 | # Frame 3: Open frame (4+3) | |
| 37 | game.roll(4) | |
| 38 | game.roll(3) | |
| 39 | ||
| 40 | # Frame 4: Strike | |
| 41 | game.roll(10) | |
| 42 | ||
| 43 | # Frame 5: Strike | |
| 44 | game.roll(10) | |
| 45 | ||
| 46 | # Frame 6: Open frame (2+3) | |
| 47 | game.roll(2) | |
| 48 | game.roll(3) | |
| 49 | ||
| 50 | # Frame 7: Spare (6+4) | |
| 51 | game.roll(6) | |
| 52 | game.roll(4) | |
| 53 | ||
| 54 | # Frame 8: Strike | |
| 55 | game.roll(10) | |
| 56 | ||
| 57 | # Frame 9: Open frame (1+2) | |
| 58 | game.roll(1) | |
| 59 | game.roll(2) | |
| 60 | ||
| 61 | # Frame 10: Strike + Spare + Fill ball (10+5+5) | |
| 62 | game.roll(10) | |
| 63 | game.roll(5) | |
| 64 | game.roll(5) | |
| 65 | ||
| 66 | # Calculate expected score: | |
| 67 | # Frame 1: 10 + 5 + 5 = 20 | |
| 68 | # Frame 2: 5 + 5 + 4 = 14 | |
| 69 | # Frame 3: 4 + 3 = 7 | |
| 70 | # Frame 4: 10 + 10 + 2 = 22 | |
| 71 | # Frame 5: 10 + 2 + 3 = 15 | |
| 72 | # Frame 6: 2 + 3 = 5 | |
| 73 | # Frame 7: 6 + 4 + 10 = 20 | |
| 74 | # Frame 8: 10 + 1 + 2 = 13 | |
| 75 | # Frame 9: 1 + 2 = 3 | |
| 76 | # Frame 10: 10 + 5 + 5 = 20 | |
| 77 | # Total: 20 + 14 + 7 + 22 + 15 + 5 + 20 + 13 + 3 + 20 = 139 | |
| 78 | ||
| 79 | self.assertEqual(game.score(), 139) | |
| 80 | ||
| 81 | def test_consecutive_strikes(self): | |
| 82 | """Test consecutive strikes in early frames.""" | |
| 83 | game = BowlingGame() | |
| 84 | ||
| 85 | # Frames 1-3: Three consecutive strikes | |
| 86 | game.roll(10) | |
| 87 | game.roll(10) | |
| 88 | game.roll(10) | |
| 89 | ||
| 90 | # Frame 4: Open frame (2+3) | |
| 91 | game.roll(2) | |
| 92 | game.roll(3) | |
| 93 | ||
| 94 | # Fill remaining frames with gutter balls | |
| 95 | for _ in range(12): | |
| 96 | game.roll(0) | |
| 97 | ||
| 98 | # Calculate expected score: | |
| 99 | # Frame 1: 10 + 10 + 10 = 30 | |
| 100 | # Frame 2: 10 + 10 + 2 = 22 | |
| 101 | # Frame 3: 10 + 2 + 3 = 15 | |
| 102 | # Frame 4: 2 + 3 = 5 | |
| 103 | # Frames 5-10: 0 | |
| 104 | # Total: 30 + 22 + 15 + 5 = 72 | |
| 105 | ||
| 106 | self.assertEqual(game.score(), 72) | |
| 107 | ||
| 108 | if __name__ == "__main__": | |
| 109 | unittest.main() |
| Test Name | Status |
|---|---|
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.