Crafting Java with Test-Driven Development, Part 8: It's Just Code
- Replacing Reminders with Code
- Improving Readability
- Using a New Deck for Each Hand
- Gentlemen, Place Your Bets
- Wrapping Up
Replacing Reminders with Code
In the last installment, we added a good chunk of code to the Texas Hold ’Em application. Our application now supports the following features:
- Dealing an entire hand, including community cards
- Dealing a series of hands, which requires removing cards from all players and from the community after each hand and moving the button after each hand
- Collecting the small and big blinds
- Managing a player’s stack of chips
- "Peeking" at the cards to be dealt from a Deck, for the purpose of simplifying our tests
We also left two reminders in the source: a failing test that said we need to worry about collecting the blinds with each hand, and a comment that said we needed to ensure that a fresh deck was used for each hand.
We left the fail point at the end of the GameTest test method testHandFlow:
public void testHandFlow() { ... fail("need to ensure blinds are extracted properly"); }
Revisiting the code in GameTest, it seems as if we should flesh out testBlinds instead of modifying testHandFlow. The code in testBlinds now only tests blinds extracted for a single hand. We want to ensure that as the button moves, the blind extractions also move. An updated test demonstrates this specification (see Listing 1).
Listing 1 A more robust testBlinds method.
public void testBlinds() { addThreePlayers(); game.setButton(3); game.startHand(); assertEquals(STAKE - SMALL, player1.chipCount()); assertEquals(STAKE - BIG, player2.chipCount()); assertEquals(STAKE, player3.chipCount()); finishHand(); game.startHand(); assertEquals(1, game.buttonPosition()); assertEquals(STAKE - SMALL, player1.chipCount()); assertEquals(STAKE - BIG - SMALL, player2.chipCount()); assertEquals(STAKE - BIG, player3.chipCount()); finishHand(); game.startHand(); assertEquals(2, game.buttonPosition()); assertEquals(STAKE - SMALL - BIG, player1.chipCount()); assertEquals(STAKE - BIG - SMALL, player2.chipCount()); assertEquals(STAKE - BIG - SMALL, player3.chipCount()); finishHand(); }
The code in testBlinds (which passes immediately, by the way) now iterates through three hands. The test code calls game.startHand() to initialize each hand, and calls a new method, finishHand(), to properly close out each hand. We define the method finishHand in GameTest as follows:
private void finishHand() { dealAllCardsInHand(); game.stopHand(); }
Prior to asserting against the chip counts of each of the players, it helps to know what the button position is, in order to understand whose chip counts should be decremented. (Remember that the player to the left of the button is responsible for posting the small blind, and the second player to the left is responsible for the big blind.) Instead of adding a comment to the code in testBlinds, we add an assertion:
assertEquals(2, game.buttonPosition());
The assertion is as clear as a comment, and adds one more bit of protection. If you have an opportunity to replace freeform comments with executing code, take it!
We still have an ugly little comment left in the GameTest code:
// missing tests: // - use a new deck each time!