## Tuesday, 1 December 2009

### Playing Cards with Haskell

As my first attempt at writing a reasonably complex lump of code in Haskell, I thought I'd try and model a card game called Klondike Solitaire. Apparently Solitaire is complex enough that:

... the odds of winning a standard game of non-Thoughtful Klondike are currently unknown. It has been said that the inability for theoreticians to calculate these odds is "one of the embarrassments of applied mathematics

The first step is to try and model the playing cards themselves. Cards have both a Suit and a Value.

`  data Suit = Clubs            | Diamonds            | Hearts            | Spades              deriving (Eq,Enum,Show,Bounded)  data Value = Ace             | Two             | Three             | Four             | Five             | Six             | Seven             | Eight             | Nine             | Ten             | Jack             | Queen             | King             deriving (Eq,Enum,Show,Bounded)  data Card = Card Value Suit              deriving (Eq,Show)`

Suit and Value both derive Eq (for equality), Show (for printing), Enum (for successor and predecessor functions) and Bounded (because they are within bounds). We can now define a complete deck of cards with a simple list comprehension.

`  allCards :: [Card]  allCards = [Card x y | x <- [Ace .. King],  y <- [Clubs .. Spades]]`

Next there are a bunch of helper functions which seem like they'll be generally useful.

`  color :: Card -> Color  color (Card _ s) | s == Clubs || s == Spades = Black                   | otherwise = Red  value :: Card -> Value  value (Card x _) = x  -- |Are the two cards alternate colours?  alternateColors :: Card -> Card -> Bool  alternateColors a b = color a /= color b  -- |Does the second card follow the first?  follows :: Card -> Card -> Bool  follows (Card King _) _ = False  follows (Card v1 _) (Card v2 _) = succ v1 == v2`

`succ` gives the successor of a given function. I don't think I can define Card as an instance of Enum because, depending on the context, the successor could be one of multiple values (e.g. the successor to `Card Ace Spades` might be a `Card Two Spades` or a `Card Two Hearts` depending on the context.

The `-- |` syntax is an indicator for the Haddock documentation tool so that you can associate the comment with the declaration.

Next time, I'll look at defining the types for Klondike Solitaire!