module CardDeck ( Card , CardType (..) , CardValue (..) , CardStatus (..) , Stack , generateDeck , generateShuffledDeck , showCard , hideCard , flipCard , matchType , matchValue , matchColor ) where import Shuffle ---------------------------------------------------------------------- -- Representation of the Standard 52-card deck. -- -- Extra support for handling piles of cards, hiding and showing -- -- cards and checking if two match given a property. -- ---------------------------------------------------------------------- ----------------------------- Constants ------------------------------ -- Colors of cards data CardType = Clubs | Diamonds | Hearts | Spades | NoneType deriving (Show, Enum, Eq) -- Values of cards data CardValue = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | NoneValue deriving (Show, Enum, Eq) data CardStatus = Hidden | Visible deriving (Show, Eq) -- A card has a type and a value and is either shown or hidden. type Card = (CardType, CardValue, CardStatus) -- A stack of cards type Stack = [Card] ---------------------------------------------------------------------- -- Generate a standard 52-card deck, with values by CardValue and types -- by CardType. Cards are hidden by default. generateDeck :: Stack generateDeck = [(cType, cValue, Hidden) | cType <- types, cValue <- values] where types = init $ enumFrom Clubs values = init $ enumFrom Ace -- Generate a standard 52-card deck and shuffle all cards randomly. generateShuffledDeck :: Stack generateShuffledDeck = shuffle generateDeck -- Show a card. showCard :: Card -> Card showCard (t, v, _) = (t,v,Visible) -- Hide a card. hideCard :: Card -> Card hideCard (t, v, _) = (t,v,Hidden) -- Flip the card. If it was visible, it is now hidden and vice versa. flipCard :: Card -> Card flipCard c@(_, _, Visible) = hideCard c flipCard c@(_, _, Hidden) = showCard c -- Check if two cards match type. matchType :: Card -> Card -> Bool matchType (t1, _, _) (t2, _, _) = t1 == t2 -- Check if two cards match color. matchValue :: Card -> Card -> Bool matchValue (_, v1, _) (_, v2, _) = v1 == v2 -- Check if two cards have the same color. matchColor :: Card -> Card -> Bool matchColor (t1, _, _) (t2, _, _) = t1 == t2 || (fromEnum t1 + fromEnum t2) `elem` [3, 6]