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.
  • Test Deletion Is a Privileged Operation
    The cheapest way for an agent to make a failing test pass is to delete it. That is logical for the agent and catastrophic for the codebase. Tests are append-only by default. Deletion needs a human author, a separate commit, and a separate review.
  • The Instruction File Is Not the Discipline
    Teams that want their agent to do TDD reach for the instruction file. The TDAD paper measured this directly: adding a 'do TDD' instruction raised regressions by nearly two-thirds. Contextual test discovery cut them by seventy percent. The instruction is theatre. The codebase's test surface is the discipline.