Code Kata

Any seasoned programmer who has tried doing Test-Driven Development (TDD) knows that it is a completely different paradigm of development from traditional methods.  So for most of us, it takes a lot of practice to become proficient at TDD.  This kata provides a simple exercise to practice the 3 basic laws of Test-Driven Development.

The Game of Bowling

A bowling game is comprised of ten frames and gives each player two balls (two chances) during each frame to knock down as many of the ten pins as they can.  Expand the section below to learn how to score a game of bowling.

In this example, as we begin the game in the first frame, a particular player (we’ll call him Bob) rolls his first ball and knocks down 1 pin.  Then on his second ball, he knocks down 4 more pins, which give him a score of 5 for the first frame (1 pin for the first ball + 4 pins for the second ball).  Then in the second frame, Bob knocks down 4 pins with his first ball, then 5 more pins with his second ball.  We add 4 + 5, which gives him a score of 9 for the second frame. For a cumulative game score, we simply add the scores for all the frames bowled so far.  In this case, the score for frame #1 was 5 and the score for frame #2 was 9, so 5 + 9 = 14.  The score written at the bottom of each frame is a cumulative game score.

Continuing in the third frame, Bob knocks down 6 pins with his first ball, then he knocks down the remaining 4 pins with his second ball.  When a player knocks down all 10 pins with two balls, this is called a spare and this example (above) shows how we draw a spare.  A spare is scored as 10 plus the next ball rolled.  In this case, Bob’s next ball (in the fourth frame) knocked down 5 pins, so his score for the third frame is 15.  Therefore, his cumulative game score is 14 + 15, which equals 29.

Bob scored another spare in the fourth frame, but then in the fifth frame, he knocked down all ten pins on his first roll.  This is called a strike.  A strike is scored as 10 plus the next two balls.  In this case, Bob did not knock down any pins with his first ball of the sixth frame and knocked down only 1 pin with his second ball.  This gives him a score of 11 for the fifth frame with a cumulative game score of 60.

This continues until the tenth frame where Bob knocked down 2 pins on his first ball, then he rolled a spare with his second ball.  Therefore, Bob gets to roll another ball in order to score the spare — which he ended up knocking down 6 pins, giving him a final game score of 133.

Start with a High-Level Design

Following is a suggested high-level design for this application.  However, as you apply the laws of TDD, don't get hung up on following this design.  Let this serve as a starting point and provide some basic vocabulary for your application.  It's okay if your code takes you down a separate path from this design.  That often happens with TDD, which is exactly how good architectures evolve.

One Possible Design

Start with a Game class, which has two methods: Roll and Score.  The Roll method take the number of pins knocked down for a given game.  The Score method is called at the end of the game and returns the score of the game.  Next is the Frame class — and a Game has 10 frames.  The Frame class has one function, Score, which returns the score for a given frame.  However, in the case of a spare or strike, the Score function will need to look ahead to the next frame to score the current frame — we therefore have the reference for the frame object back onto itself, indicating that dependency.  Next is the Roll class, and a Frame has 1 or 2 Rolls, except in the tenth frame, where it will have 2 or 3 rolls — as indicated by the sub-type Tenth Frame, which has one additional role (as indicated).  The Roll class has a private attribute of pins which holds the number of pins knocked down on a given roll. 

3 Laws of Test-Driven Development
  1. Write no production code except to pass a failing test.
  2. Write only enough of a test to demonstrate a failure.
  3. Write only enough production code to pass the test.

This is a kata that is borrowed from Bob Martin, who often uses this example to teach the practice of Test-Driven Development.

Related Items

subject Article

Why Bother With TDD?

Does it really make sense to test code that hasn’t even been written yet?  Or to disrupt your development mojo every minute to stop, write tests, and refactor code?  It does if you want to deliver software faster, through better code, with fewer defects, and greater agility.  As software development leaders, it is important to understand that Test Driven Development goes well beyond quality control.

Read More
school Training

Principles & Practices of Test-Driven Development

This course teaches the principles and practices of Test-Driven Development (TDD) and demonstrates how proper software design evolves through application of the eXtreme Programming principle of Test First.  Unit testing principles are introduced, along with a thorough discussion on the benefits of TDD.  An application is developed (from start to finish) during this course to explain step-by-step and demonstrate first-hand how a high quality, testable design evolves by applying the three laws of Test-Driven Development.

Learn More schedule 3 Hours
school Training

Unit Testing and Beyond

This course teaches the principles and practices of unit testing, along with core techniques for writing testable software and avoiding test smells.  Dependency Inversion is taught as an effective method for isolating the system under test, along with test doubles for overriding behavior.  Test-Driven Development (TDD) is also taught and demonstrated to show how proper software design evolves through application of the XP principle of Test First.  An application is developed during this course to demonstrate how a high quality design evolves by applying the three laws of TDD.

Learn More schedule 6 Hours