module PlayingCards.Deck( card, spades, hearts, clubs, diamonds, ace, king, queen, jack, ten, nine, eight, seven, six, five, four, three, two, dealCard, containsCard, newDeck, cardsLeft) where import Data.List import Test.QuickCheck data Deck = Deck [Card] deriving (Eq, Ord, Show) data Card = Flat Rank Suit deriving (Eq, Ord, Show) card = Flat data Suit = Spades | Hearts | Diamonds | Clubs deriving (Enum, Eq, Ord, Bounded, Show) spades = Spades hearts = Hearts diamonds = Diamonds clubs = Clubs data Rank = Ace | King | Queen | Jack | Ten | Nine | Eight | Seven | Six | Five | Four | Three | Two deriving (Enum, Eq, Ord, Bounded, Show) ace = Ace king = King queen = Queen jack = Jack ten = Ten nine = Nine eight = Eight seven = Seven six = Six five = Five four = Four three = Three two = Two newDeckCards :: [Card] newDeckCards = [Flat r s | r <- [minBound..maxBound], s <- [minBound..maxBound]] newDeck :: Deck newDeck = Deck newDeckCards cardsLeft :: Deck -> Int cardsLeft (Deck d) = length d dealCard :: Deck -> (Card, Deck) dealCard (Deck []) = error "Attempt to deal from empty deck" dealCard (Deck (c:rest)) = (c, Deck rest) containsCard :: Card -> Deck -> Bool containsCard c (Deck d) = elem c d instance Arbitrary Suit where arbitrary = elements [Spades, Hearts, Clubs, Diamonds] instance Arbitrary Rank where arbitrary = elements [Ace, King, Queen, Jack, Ten, Nine, Eight, Seven, Six, Five, Four, Three, Two] instance Arbitrary Card where arbitrary = do suit <- arbitrary rank <- arbitrary return $ Flat suit rank instance Arbitrary Deck where arbitrary = do cardsToRemove <- arbitrary return $ Deck (newDeckCards \\ cardsToRemove)