Poker hand analyser: Difference between revisions

m
Line 1,956:
=={{header|Haskell}}==
===Basic Version===
<lang Haskell>import Data.List (group, nub, any, sort, sortBy)
import Data.ListMaybe (group, nub, any, sort, sortBymapMaybe)
import Data.Maybe (catMaybes)
 
data Suit = Club | Diamond | Spade | Heart deriving (Show, Eq)
 
data Rank = Ace | Two | Three | Four | Five | Six | Seven |
Eight | Nine | Ten | Jack | Queen | King
deriving (Show, Eq, Enum, Ord, Bounded)
 
data Card = Card { suit :: Suit
, rank :: Rank
} deriving (Show, Eq)
 
Line 1,974 ⟶ 1,973:
 
isSucc :: (Enum a, Eq a, Bounded a) => [a] -> Bool
isSucc [] = True
isSucc (x:[x]) = True
isSucc (x : y : zs) | x /= maxBound && y == succ x = isSucc $ y : zs
isSucc _ = False
 
parseCard :: String -> Maybe Card
parseCard [] = Nothing
parseCard xs = Card <$> parseSuit <*> parseRank
where
where parseRank = case r of "a" -> Just Ace
"2" -> Just Two
"3a" -> Just ThreeAce
"42" -> Just FourTwo
"53" -> Just FiveThree
"64" -> Just SixFour
"75" -> Just SevenFive
"86" -> Just EightSix
"97" -> Just NineSeven
"108" -> Just TenEight
"j9" -> Just JackNine
"q10" -> Just QueenTen
"kj" -> Just KingJack
"q" -> Just Queen
_ -> Nothing
"k" -> Just King
where r = init xs
_ parseSuit = case s of '♥' -> Just HeartNothing
where r = init xs
'♦' -> Just Diamond
parseSuit = case s of
'♣' -> Just Club
'' -> Just SpadeHeart
'♦' -> Just Diamond
_ -> Nothing
'♣' -> Just Club
where s = head $ reverse xs
'♠' -> Just Spade
_ -> Nothing
where s = last xs
 
nameHand :: String -> String
nameHand s | invalidHand = ": invalid"
| straight && flush = ": straight-flush"
| invalidHand = ": invalid"
| straightofKind 4 && flush = ": straightfour-of-a-flushkind"
| ofKind 43 && ofKind 2 = ": four-of-afull-kindhouse"
| ofKindflush 3 && ofKind 2 = ": full-houseflush"
| flushstraight = ": flushstraight"
| ofKind 3 = "2" : three-> Just Twoof-a-kind"
| straight = ": straight"
| ofKinduniqRanks == 3 = ": three-of-atwo-kindpair"
| uniqRanks == 34 = ": twoone-pair"
| uniqRanksotherwise == 4 = ": onehigh-paircard"
where
| otherwise = ": high-card"
where cards = catMaybes $ map parseCard $= mapMaybe parseCard (words s)
sortedRank = sort $ map rank cards
ranks ranks = rankCountTuple cards
where
where rankCountTuple xs = sortedGroups $ map rankCount $ groupedByRank
rankCountTuple xs = sortedGroups $ map whererankCount groupedByRank = group sortedRank
where
rankCount c@(x:_) = (x, length c)
groupedByRank = group sortedRank
sortedGroups = sortBy (\(_, n) (_, n') -> compare n' n)
rankCount c@(x uniqRanks: _) = (x, length ranksc)
sortedGroups ofKind n = anysortBy (\(_, yn) (_, n'') -> compare n'' == yn) ranks
uniqRanks = length ranks
straight = isSucc sortedRank || sortedRank == acesHigh
ofKind n flush = and $ mapany (\c(_, y) -> s'n == suit cy) cardsranks
straight straight = isSucc sortedRank || sortedRank == acesHigh
flush = all (\c -> s'' == suit c) cards where s'' = suit $ head cards
invalidHand = length (nub cards) /= 5
| invalidHand = ":length invalid"(nub cards) /= 5
 
testHands :: [String]
testHands =
[ "2♥ 2♦ 2♣ k♣ q♦"
, "2♥ 5♥ 7♦ 8♣ 9♠"
Line 2,046 ⟶ 2,049:
 
main :: IO ()
main = mapM_ (putStrLn $ map. (\s -> s <> nameHand s)) testHands</lang>
</lang>
{{out}}
<pre>
Anonymous user