Bowling Game

Level: Advanced 60–90 min

Concepts: Edge CasesState

Solutions: C# | TypeScript | Python


Create a program to score a game of ten-pin bowling.

Requirements

  1. Calculate the score for a game of ten-pin bowling
  2. Handle all valid bowling scenarios:
    • Regular frames (sum of pins knocked down)
    • Spares (10 pins in two rolls, bonus is next roll)
    • Strikes (10 pins in one roll, bonus is next two rolls)
    • 10th frame special cases (up to three rolls)
  3. Validate input:
    • Number of pins must be between 0 and 10
    • Sum of pins in a frame (except last) must not exceed 10
    • Proper number of rolls based on game progress

Test Cases

ScenarioRollsScoreNotes
All Gutter Balls0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,00No pins knocked down
All Ones1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, 1,120One pin per roll
One Spare5,5, 3,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,016Spare + bonus
One Strike10, 3,4, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,024Strike + bonus
Perfect Game10, 10, 10, 10, 10, 10, 10, 10, 10, 10,10,10300All strikes
All Spares5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5, 5,5,5150All spares

Edge Cases to Consider

  • Invalid number of pins (>10 or <0)
  • Invalid frame totals (>10 in a frame)
  • Wrong number of rolls for the game state
  • Invalid bonus rolls in 10th frame
  • Empty or null input

Tips

  • Start with the simplest case (all zeros)
  • Add support for regular frames first
  • Then add spares, then strikes
  • Handle the 10th frame as a special case
  • Consider using a Frame class to encapsulate frame logic

Reference Walkthrough

Full C#, TypeScript, and Python implementations live at tddbuddy-reference-katas/bowling-game — the same six scenarios across all three languages, walked commit-by-commit through the TDD cycle.

This is a Pedagogy mode kata — the walkthroughs step through the TDD cycle commit-by-commit. Watch the gear shift from low (fake-it, sum) to middle once the scoring loop’s two-mode index (frame vs roll cursor) lands. The teaching point is the class that does not get written: two reflect — commits mark the moments the author was tempted to extract a Frame type and chose not to — the Frame concept lives in the rollIndex += 1 vs rollIndex += 2 advance, not in a class. See the repo’s Gears section for why resisting a premature abstraction is itself a TDD skill.


  • Examples Pin Intent. Properties Pin the Invariants.
    Example-based tests anchor scenarios in the team's vocabulary. Property-based tests anchor invariants across the input space. The agent needs both axes, and most suites only carry one.
  • Tamper-Resistant Test Design Is What the Suite Now Owes the Codebase
    Tests were a contract the team made with itself. Agents made the suite an attack surface. Tamper-resistant test design is what the suite now owes the codebase: expensive to spoof, redundantly verified, partially hidden, and impossible to delete without a separate review.
  • A Flaky Test Is a Corrupted Reward Signal
    A flaky test is an annoyance to a human and a catastrophe to an agent. The human re-runs it and moves on. The agent reads the random red as a defect and changes correct code. Determinism is the precondition for letting an agent close the loop unattended.