game-probability-1.1: Numeric/Probability/Game/PlayingCards.hs
-- | A module containing some simple data definitions for a deck of playing cards.
module Numeric.Probability.Game.PlayingCards (PlayingCard(..),Suit(..),Rank(..),AceLowRank(..),deck,
sameSuit, sameRank) where
import Data.Function (on)
import Numeric.Probability.Game.Cards
-- | The rank of playing cards. The ranking is specified ace-high, as this is
-- how many games operate. If you wish to have an ace-low ordering you can use
-- the 'AceLowRank' newtype.
data Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack
| Queen | King | Ace
deriving (Bounded, Enum, Eq, Ord, Show, Read)
-- | A wrapper for 'Rank' where the Ord, Enum and Bounded instances are adjusted
-- to list Ace as the lowest item rather than the highest.
newtype AceLowRank = AceLow {alRank :: Rank}
deriving (Eq, Show, Read)
instance Bounded AceLowRank where
minBound = AceLow Ace
maxBound = AceLow King
instance Enum AceLowRank where
fromEnum (AceLow Ace) = 0
fromEnum (AceLow x) = fromEnum x + 1
toEnum 0 = AceLow Ace
toEnum n = AceLow $ toEnum (n - 1)
instance Ord AceLowRank where
compare = compare `on` fromEnum
-- | The standard four suits of playing cards. The ordering on them is arbitrary
-- (alphabetical, in fact).
data Suit = Clubs | Diamonds | Hearts | Spades
deriving (Eq, Ord, Show, Read)
-- | A playing card with a rank and suit. The ordering on them is arbitrary (by
-- rank then by suit).
data PlayingCard = PlayingCard {rank :: Rank, suit :: Suit}
deriving (Eq, Ord, Show, Read)
-- | The standard full deck of 52 playing cards.
deck :: Cards PlayingCard
deck = makeCards [PlayingCard r s | r <- [minBound .. maxBound], s <- [Clubs,Diamonds,Hearts,Spades]]
-- | Checks if the two cards have the same suit.
sameSuit :: PlayingCard -> PlayingCard -> Bool
sameSuit = (==) `on` suit
-- | Checks if the two cards have the same rank.
sameRank :: PlayingCard -> PlayingCard -> Bool
sameRank = (==) `on` rank