Sunday, March 20, 2011

TDD Spider Solitaire

Another question about TDD from me. I have read some articles and book chapters about TDD and I understand why you should TDD and I understand the simple examples but it seems when I am trying this out in the real world I get stuck very easy.

Could you give me some simple TDD examples if you were to program the well known Spider Solitaire that comes with Windows Vista? Which tests would you start with?

From stackoverflow
    1. list the features of spider solitaire [i don't play card games]
    2. describe how you would test each feature
    3. do it
  • Well, when you're asking about TDD for spider solitaire, you're basically asking about how to design such a game. The tests will be the consequence of design decisions. Solitaire is a simple game, but designing such a game from scratch isn't trivial (there's more than one way to go about it).

    You might want to start with something much simpler to design, like a number guessing game (where the system generates a random number and you try to guess it in as few tries as possible).

    Some features of such a simple game would be:

    1. Feature to generate the secret number randomly between 1 and 10. Generating a new number starts a new game.
    2. Feature to compare whether a player's input is higher or lower than that number, or if the guess is right on
    3. Feature to count the number of guesses

    From that you might try these tests (just as crude examples, but easily coded):

    1. Run your generator 1000 times. Make sure secret_number >= 1 && secret_number <= 10 every time.
    2. For a sample set of numbers (randomly generated), does your comparison function return "HIGH" when number > secret_number, "LOW" when number < secret_number, and "WIN" when number == secret_number?
    3. Repeat the previous test, but track the number of items you test. When "WIN" is returned, make sure your counter feature matches your test's number of items.

    This is just a very rough outline, and by no means complete. But you can see from the english descriptions that code examples would be even more verbose. I think if you want more specific answers, you have to ask a more specific question.

    furtelwart : Shouldn't it be "secret_number >= 1"?
  • Solitaire games involve cards.

    So, you think of a Card class. You write some tests for individual Card objects. You write your Card class to pass the tests.

    You need a deck that shuffles and deals into the layout. You think of the Deck class and the shuffle algorithm and how it maintains state for dealing. You write some tests for a Deck that shuffles and deals. You write your Deck class to pass the tests. [Note, this requires a mock random number generator that isn't actually random.]

    Solitaire games involve a layout with empty spaces and cards. Some empty spaces of rules (Kings only or Aces only). Solitaire games sometimes involve a stock, more-or-less the remains of the Deck.

    So you think of a Layout class with spaces for cards. You write some tests for the Layout and put in various Cards. You write your Layout class to pass the tests.

    Then there's rules on what cards can be moved from the layout. Whole stacks, sub-stacks, top cards, whatever. You have an AllowedMove or GameState or some such class. Same drill. Define roughly what it does, write tests, finish the class.

    You have user interface and display stuff. The drill is the same.

    1. Rough out the class.

    2. Define the tests.

    3. Finish the class.

    etc.

    I cover this in detail in a book on OO Design.

  • First you should separate out the GUI from the engine. TDDing the GUI is the hardest part, so you shall keep your GUI layer as thin as you can. Google for "the humble dialog box" and read the tddui list on Yahoo! groups.

    The engine layer will implement the game rules. I'm not sure how the Spider solitaire differs from the ancient solitaire (i.e. from Windows 3.1) on which I based the following:

    Here is the initial test list I will start from:

    • you can always move a card to an empty stack
    • a card has a value, and one can compare to cards
    • you can only move a card to a non-empty stack when the card on the top is lower than the moved card
    • you can always move several cards to an empty stack
    • you can only move several cards to a non-empty stack when the card on the top is lower than the moved card
    • when you move all the turned cards from a stack, the top card can be returned (or shall be automatically returned ?)
    • you can take a the first card from the dock and put in an any stack (?)

    I'me getting unsure about the rules, but I think this is enough to get the idea.

    Last, start with the simplest test, add tests to the list when you have a new test idea, or when you find yourself questioning: what happen if ... .

0 comments:

Post a Comment