A great time was had by all March 25, 2015, at Ruby Hack Night. At the event about 30 Ruby developers teamed in small groups and pair-programmed Uncle Bob’s Bowling Game Kata in Ruby. We used everything in our TDD toolkit to implement the solution quickly and cleanly. It was a bigger challenge than many had anticipated!
“Team Projector”, which was the five or so guys working with me on the big screen, was utterly awesome at brainstorming ideas. Thanks to each of you for your contributions. Your efforts have been noted and your code is now proudly posted in the david_final
branch of the Github project space.
Comments on the kata:
1. We decided to separate the concepts of frame score (shown to the player and used in final scoring), pin count from rolls (used for strike and spare calculations), and pin count in a frame (used for open frames and the important tenth frame). The method #pin_count_from_rolls
is the only method that traverses the next_frame
links to find rolls in later frames.
2. We had it wrong. The rules are: the tenth frame is three balls if you strike or spare, otherwise two. The tenth frame pin count is simply the sum of the rolls and does not compound the second and/or third rolls. So, 12 strikes is a perfect game, the tenth frame has a score of 30 with three strikes 10 x 3 = 30 with no compounding. The rule also corrected our score for a sample game we pulled from the ‘net (see our third-last test – the correct score is 166, not 169).
3. Based on the above we made it so additional balls thrown after the end-of-game are ignored (it was a one-liner based on our Frame#bowled?
method)
4. We found it useful to implement some simple #frames_inspect
and #rolls_inspect
methods to output a rough scorecard for debugging certain edge-cases.
In the end, the introduction of the tenth frame caused a lot of havoc with our earlier design. We dealt not only with the creation of the new functionality (to get a green), but quite a bit of refactoring of the TenthFrame implementation and the Frame implementation (for instance, generalizing the Frame class to the point that TenthFrame is only three override methods) that cause many “reds” and broken earlier tests before we got back to green.
We wish we had done a better job of approaching the refactoring in the final step, as it felt like the TDD workflow was lost beneath all of the refactoring. In hindsight, we might have written Unit Tests for the Frame
class, which would have allowed us to introduce the TenthFrame
class in a measured way. This is truly the correct approach and I believe we both took longer to deliver the final code, and also are now lacking Frame tests. This is what katas are for, and we will not make the same mistake next time!
Feel free to contribute comments! See you all next time!
[Click for more articles from our Development series]
[Click for more articles from our Workshop series]
[Click to learn more about Ryatta]