TDD Pairing Sessions - Building a Go Game
11 lessons 10 h 50 min 1 section
Start course Watch on YouTube playlist (external link, opens in new tab)
Over 8 hours of hardcore live pairing.
About this course
Roy Osherove and Raymond Lim, who wants to build a Go game, pair program (external link, opens in new tab) a Go game engine test first in C# with Visual Studio, ReSharper and NUnit (external link, opens in new tab). Starting from an empty board, they add tests for removing surrounded stones, komi and finding a winner, taking small steps that remove one assumption at a time. Later sessions add a DSL (external link, opens in new tab) for drawing boards in tests, try NCrunch and Mighty Moose, refactor into rules, strategies and removal detectors, and spend long stretches debugging their own test code.
Curriculum
Section 1
The Sessions
The section is a series of recorded pair-programming sessions in which Raymond Lim and Roy Osherove build a Go game engine test first in Visual Studio with ReSharper and NUnit. Their tests cover empty positions, removing surrounded stones, komi and finding the winner by counting owned cells, while the code is refactored into rules, winner strategies, a stone remover and removal detectors. Several sessions go into debugging, including line breaks that differ between machines and swapped X and Y positions in a DSL that draws the board in a string.
- Understanding the Problem Duration 1:53:39
The pair agree how to pair program, set up Visual Studio with NUnit, ReSharper and TestDriven.NET, and write a first test that a new board position is empty. They cover units of work with three kinds of end results, a ReSharper test template, factory methods instead of setup methods, and removing assumptions one at a time. Then they drive out removing a black stone surrounded by white stones, in a visually laid-out test, and debug an index out of range bug at the board's edge.
- Mapping Moves Duration 30:05
In session two Roy Osherove and Raymond Lim list the missing moves and features in an Excel file, with Raymond explaining the rules of Go. The list includes surrounding groups, invalid moves, switching turns, the winner, handicaps, board sizes, saving games and komi, which means there is never a tie. Aiming for a game that can be finished, they test that white wins by default because of komi, through a public who-wins method, since komi is internal.
- Stoned and Board Duration 30:14
The pair look for the simplest test that proves black can win, and the Excel file explains scoring: points for territory, a point lost per removed stone. They consider an event log for calculating the score, but choose a test that adds stones so black owns at least one cell. The laziest code, where the last stone added wins, passes, so a new test has white play last while black still wins.
- Colors and Winners Duration 48:10
The pair check whether a cell is fully surrounded by a color passed as a parameter, and add an empty color as the enum default because a new matrix is all black. A komi mode flag, off once a stone is played, keeps the default test passing, and logic moves into a new rules class. A broken large refactoring is undone and redone in smaller steps, and the board forwards get winner to the rules, explained with the Law of Demeter.
- Finding a Winner Duration 1:01:59
In session three the pair remove the hard-coded corner cell from the winner check, duplicating passing tests instead of changing them and changing one assumption per test. Debugging shows the board starts all black, so they first write a failing test where white should win by komi, then fix the enum and an off-by-one edge check. They loop over the board to find surrounded cells, add an edge constant and remove the assumption that black always wins.
- Total Noob Fail Duration 1:26:57
Session six starts with five tests failing on one machine but passing on Raymond Lim's, caused by line breaks in a string the test code splits. The first cell strategy, which really returned the last cell, becomes a strategy that counts each color's cells, and a planted bug shows the new test can fail. After removing the assumption that the surrounding color is white, work on two connected stones ends with finding X and Y swapped in the test's fill board helper.
- A DSL for our Tests Duration 55:07
In session five the pair turn on NCrunch, which runs the tests when the code changes and shows line coverage. For counting territories they write tests where one color owns one cell and the other two, but the tests pass unexpectedly and they cannot find out why. They build a DSL that draws the board as a string with numbered rows and B and W stones, parsed by splitting and trimming lines, and convert the other tests to it.
- A Refactoring Dillemma Duration 43:47
In session four the pair use Mighty Moose, a free Visual Studio plugin that runs affected tests on save, and start replacing the komi mode check with the strategy pattern. Komi and first cell winner strategies inherit from a winner finding strategy base class that gets the board in its constructor, and the komi flag and current winner field go. The change breaks the test where white should win by komi when nobody owns a cell, raising the dilemma of whether counting points will replace the strategies.
- Debugging Excursions Duration 51:29
In session seven a test fails on Raymond Lim's machine, and NCrunch coverage markers show the almost surrounded code never runs. Conditional breakpoints and moving stones away from the edge point to a bug near the edges, so they add tests near the top and left edges. Replacing the fill board call with add stone calls shows the bug is in the DSL, whose X and Y swap was never committed, and they start a check below the stone for vertical pairs.
- The Big Refactor Duration 1:28:13
In session eight the pair refactor before adding a group of three, guided by don't repeat yourself and the single responsibility principle, since simple code forces thinking about tests. Removal logic moves into a stone remover class with a removal arguments parameter object, leaving the board to manage the stones. The checks become removable detector classes returning lists of position tuples, one looping over checkpoints, and the classes move to their own files and folder.
- New Features Duration 40:06
The pair test that two stones which are not fully surrounded are not removed, and make the almost surrounded check count three edges of the other color and one of the same. The fix also checks a diagonal, which they call the board-scanning algorithm rather than a game rule, like dispersing the fog in DND games. They add test cases, then a check above the stone for vertical pairs, fixing out of bounds errors at the top edge by returning empty there.