Let's just pause here for a while and say a bit about this method of working.
The tests exercise the Hanoi game. They do this by saying either "calling this
method returns this event" (success) or "calling this method throws this
exception" (failure). The Hanoi game keeps state around, but the attributes are
completely private. There are no getter methods. The public methods (.move,
and later .remove and .add) may read attributes, but the attributes are only
written to in a private !apply method. (The ! means "private".) The
!apply method is called with an event.

So the only way to actually change the game state is to send an event of some
kind to the !apply method. This keeps us honest in a way; we have to
publicize all the important internal updates of the Hanoi game as events.

Now this last point is interesting. We introduce .remove, and suddenly we
have to go back to .move and patch a "vulnerability" that suddenly opened up.
I think many bugs are of this kind; old operations which end up in new
situations for which they were not designed.

Adding disks

You can add a disk that you removed before. We're always talking about the tiny disk in these cases, but it doesn't matter much.

At this point I realized that some of my events attributes could be improved. The design was presented as a completed fact yesterday, but it very much evolved together with the test and the implementation. It's comforting to see that that works really well.

See how easy it is to miss some cases? One could argue that this is a great
weakness of this way of developing, but I would argue the opposite: this way of
focusing on verbs and their results enhances the ability to think in terms of
these situations. Also note how small and self-contained each commit is, even
the fixes.

I'm really proud how the client turned out. Have a look at the 'final' client. I especially call your attention to the fact that we don't just list the available commands, we ask the Hanoi game for them. (Yay introspection!) Also, the print_board subroutine turned out really nice, for something that does formatted output. There's a little "cheating" that makes the command parser treat things like 'large disk' as one argument even though it's two words.

So

75 tests pass and support this hanoi game. I can't guarantee there are no
remaining bugs to find, but I'm very confident it'll be easy and even a bit fun
to integrate what we now have into the adventure game when the time comes.

Also, I imagine the subsequent posts will be a bit smaller in scope than these
two first ones. Still, this was probably a good introduction to the style of
programming we'll be using for the rest of the month. Commands, events, and
exceptions. We'll see more advantages as we go along.

Now we can leave Hanoi behind us for a while, and... let the adventure begin!