Advertisement
Yurry

Unfinished poker hands checker

Feb 17th, 2013
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.Char
  2. import Data.Ord
  3. import Data.List
  4. import Data.Maybe
  5. import Data.Function
  6.  
  7. data Suit = C | S | D | H
  8.     deriving (Show, Read, Eq, Ord)
  9.  
  10. newtype Rank = Rank Int
  11.     deriving (Eq, Ord)
  12.  
  13. instance Show Rank where
  14.     show (Rank 10) = "T"
  15.     show (Rank 11) = "J"
  16.     show (Rank 12) = "Q"
  17.     show (Rank 13) = "K"
  18.     show (Rank 14) = "A"
  19.     show (Rank n) = show n
  20.  
  21. instance Read Rank where
  22.     readsPrec _ ('T':r) = [(Rank 10, r)]
  23.     readsPrec _ ('J':r) = [(Rank 11, r)]
  24.     readsPrec _ ('Q':r) = [(Rank 12, r)]
  25.     readsPrec _ ('K':r) = [(Rank 13, r)]
  26.     readsPrec _ ('A':r) = [(Rank 14, r)]
  27.     readsPrec _ (d:r) | isDigit d = [(Rank $ digitToInt d, r)]
  28.                       | otherwise = error "Wrong rank"
  29.  
  30. type Card = (Rank, Suit)
  31. readCard :: String -> Card
  32. readCard (r:s:[]) = (read [r], read [s])
  33. readCard _ = error "Wrong card"
  34.  
  35. getRank = fst
  36. getSuit = snd
  37. type SortedHand = [Card]
  38.  
  39. readHand = sortHand . map readCard . words
  40.  
  41. data PokerHand = Kicker Rank
  42.                | Pair Rank
  43.                | TwoPairs Rank Rank
  44.                | ThreeOfAKind Rank
  45.                | Straight Rank
  46.                | Flush [Rank]
  47.                | FullHouse Rank Rank
  48.                | FourOfAKind Rank
  49.                | StraightFlush Rank
  50.     deriving (Eq, Ord, Show)
  51.  
  52. checkCombos hand = catMaybes $ map (\f -> f hand) [hasKicker, hasPair, hasTwoPairs, hasThreeOfAKind, hasStraight, hasFlush, hasFullHouse]
  53.  
  54. type CheckHand = SortedHand -> Maybe PokerHand
  55.  
  56. down LT = GT
  57. down EQ = EQ
  58. down GT = LT
  59.  
  60. sortHand :: SortedHand -> SortedHand
  61. sortHand = reverse . sortBy (comparing getRank)
  62.  
  63. getGroupRank = getRank . head
  64.  
  65. hasKicker :: CheckHand
  66. hasKicker = Just . Kicker . getGroupRank
  67.  
  68. groupRanks = reverse . sortBy (comparing length) . groupBy ((==) `on` getRank)
  69.  
  70. hasPair :: CheckHand
  71. hasPair hand = find (\g -> length g >= 2) (groupRanks hand) >>= return . Pair . getGroupRank
  72.  
  73. hasTwoPairs :: CheckHand
  74. hasTwoPairs hand = case filter (\g -> length g >= 2) (groupRanks hand) of
  75.     (g1:g2:_) -> Just $ TwoPairs (getGroupRank g1) (getGroupRank g2)
  76.     _ -> Nothing
  77.  
  78. hasThreeOfAKind :: CheckHand
  79. hasThreeOfAKind hand = find (\g -> length g >= 3) (groupRanks hand) >>= return . ThreeOfAKind . getGroupRank
  80.  
  81. hasStraight :: CheckHand
  82. hasStraight hand = findStraight (zipWith (\a b -> (diffRank a b, a)) ranks (tail ranks))
  83.     where ranks = nub $ map getRank hand
  84.           diffRank (Rank a) (Rank b) = a - b
  85.           findStraight ((1, f):(1, _):(1, _):(1, _):_) = Just $ Straight f
  86.           findStraight (x:xs) = findStraight xs
  87.           findStraight _ = Nothing
  88.  
  89. hasFlush :: CheckHand
  90. hasFlush hand = find (\g -> length g >= 5) [filter (\c -> getSuit c == s) hand | s <- [C, S, D, H]] >>= return . Flush . map getRank
  91.  
  92. hasFullHouse :: CheckHand
  93. hasFullHouse hand = findFullHouse $ groupRanks hand
  94.     where findFullHouse ((c11:c12:c13:_):(c21:c22:_):_) = Just $ FullHouse (getRank c11) (getRank c21)
  95.           findFullHouse (x:xs) = findFullHouse xs
  96.           findFullHouse _ = Nothing
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement