... 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
data Value = Ace
data Card = Card Value Suit
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
succgives 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 Spadesmight be a
Card Two Spadesor a
Card Two Heartsdepending on the context.
-- |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!