他人のHaskell日記 RSSフィード

Haskell初心者が、リハビリがてらに「ふつける」と「入門Haskell」片手に、試行錯誤するサイト。

2008-12-14

ポーカー役判定の改良  ポーカー役判定の改良 - 他人のHaskell日記 を含むブックマーク

http://haskell.g.hatena.ne.jp/taninsw/20081213/p1

isFlushとcardと、その他ごにょごにょかきかえた。


import List
import Maybe
import System.Environment

data Hand = Hand Bool Bool Bool [Int]

card []       = []
card (x:y:zs) = (x,rankInt y): card zs
  where rankInt char = let allRank = "_A23456789TJQK"
                       in  fromJust (elemIndex char allRank)

isRoyal xs  =  xs == [1,10,11,12,13]
isStraight xs  = (zipWith (-) (tail xs) xs) == [1,1,1,1] 
same xs = reverse $ sort $ map (\x-> length $ filter (\a-> x == a) xs) (nub xs)

isFlush (x:xs) = all (==x) xs

cardAnalysis xs = let ranks    = sort $ map snd xs
                      suits    = map fst xs
                      royal    = isRoyal ranks
                      straight = isStraight ranks
                      sameRanks  = same ranks
                      flush    = isFlush suits
                  in Hand flush royal straight sameRanks

instance Show Hand where
  show h = case h of 
    Hand True True  False _      -> "Royal flush"
    Hand True False True  _      -> "Straight flush"
    Hand _    _     _    (4:_)   -> "Four of a kind"
    Hand _    _     _    (3:2:_) -> "Full house"
    Hand True _     _     _      -> "Flush"
    Hand _    _     True  _      -> "Straight"
    Hand _    True  _     _      -> "Straight"
    Hand _    _     _    (3:_)   -> "Three of a kind"
    Hand _    _     _    (2:2:_) -> "Two Pair"
    Hand _    _     _    (2:_)   -> "One Pair"
    Hand _    _     _    _       ->  "No Pair"

main = getArgs >>= print.cardAnalysis.card.head

-- for testing
testData = ["SQSJSASKST","D9D7D6D5D8","C2D2S2H3H2","C2D3S2H3H2",
            "S9S4S8STSJ","C4H7D5S6H3","S6H6C5DQC6","S6HQC5DQC6",
            "S6H4C5DQC6","SJSQSKSAC2"]
test     =  map (cardAnalysis.card) testData

{-
*Main> test
[Royal flush,Straight flush,Four of a kind,Full house,Flush,Straight,Three of a kind,Two Pair,One Pair,No Pair]
-}