ポーカーの役判定
お題にしようと思っていたのに間違えてしまいました。今から変更可能でしょうか?
(説明) 当初間違ってトピックに投稿していたので、このようなコメントを付けていたのですが、 このコメントに気づいた管理人さんにお題に移していただきました。 (最初の2つだけ投稿日時が早いのはそのためです)
Posted feedbacks - Haskell
ストレートの判定がなかなかきれいにまとまりませんね。ソートしておいて隣り合う数の差で判断してみましたが……うーん。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import Data.List as List
hand :: String -> (String, Bool)
hand cards =
(case kinds of
[1, 4] -> "Four of a kind"
[2, 3] -> "Full house"
[1, 1, 3] -> "Three of a kind"
[1, 2, 2] -> "Two pair"
[1, 1, 1, 2] -> "One pair"
otherwise ->
case rdiff of
[1, 1, 1, 1] | head ranks == 10 && isFlush -> "Royal"
| True -> "Straight"
[1, 1, 1, 9] -> "Straight"
otherwise -> "No pair"
, isFlush)
where suits = List.nub [cards !! n | n <- [0,2..8]]
isFlush = length suits == 1
ranks = List.sort [rankToInt $ cards !! n | n <- [1,3..9]]
rankToInt r = case List.elemIndex r "23456789TJQKA" of Just n -> n+2
kinds = List.sort $ map length $ List.group ranks
rdiff = zipWith (-) (tail ranks) ranks
main = mapM test ["SQSJSASKST", "D9D7D6D5D8", "C2D2S2H3H2", "C2D3S2H3H2",
"S9S4S8STSJ", "C4H7D5S6H3", "S6H6C5DQC6", "S6HQC5DQC6",
"S6H4C5DQC6" ,"SJSQSKSAC2"]
where test s = putStrLn (s ++ " => " ++ (showHand $ hand s))
showHand ("No pair", True) = "Flush"
showHand (s, True) = s ++ " flush"
showHand (s, False) = s
|
data使いたがりなhaskellコード。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import System
import List(sort,group,elemIndex)
import Maybe(fromJust)
data Card = Card {suits::Suits,rank::Int} deriving Show
data Suits = S | D | H | C deriving (Read,Eq,Show)
data Hand = RF | STF | FK | FH | F | ST | TK | TP | OP | NO
read_cards :: String -> [Card]
read_cards str = map read_card $ split_2 str
where
read_card [s,r] = Card (read [s])
(fromJust (elemIndex r "DD23456789TJQKA"))
split_2 [] = []
split_2 list = let (hd,rest) = splitAt 2 list in hd : split_2 rest
instance Show Hand where
show h = case h of
RF -> "Royal flush"
STF -> "Straight flush"
FK -> "Four of a kind"
FH -> "Full House"
F -> "Flush"
ST -> "Straight"
TK -> "Three of a kind"
TP -> "Two pair"
OP -> "One pair"
NO -> "No pair"
hand :: [Card] -> Hand
hand cards
| check_st && check_flush && head rank_seq == 10 = RF
| check_st && check_flush = STF
| max_group == 4 = FK
| sort group_count == [2,3] = FH
| check_flush = F
| check_st = ST
| max_group == 3 = TK
| pair_count == 2 = TP
| pair_count == 1 = OP
| otherwise = NO
where
rank_seq = sort $ map rank cards
groups = group rank_seq
group_count = map length groups
max_group = foldl1 max group_count
pair_count = length (filter (\l->length l == 2) groups)
check_flush = all (\c->suits c==suits (head cards)) cards
check_st = normal || rank_seq == [2,3,4,5,14]
where
normal = and $ zipWith (\a b->a-b == head rank_seq) rank_seq [0..]
main = getArgs >>= print . hand . read_cards . head
-- Test
test = zip testlist (map (hand .read_cards) testlist)
testlist = ["SQSJSASKST",
"D9D7D6D5D8",
"C2D2S2H3H2",
"C2D3S2H3H2",
"S9S4S8STSJ",
"C4H7D5S6H3",
"S6H6C5DQC6",
"S6HQC5DQC6",
"S6H4C5DQC6",
"SJSQSKSAC2"]
|





xsd
#4978()
Rating6/10=0.60
引数に手札を与えると、ポーカーの役を表示するプログラムを作ってください。
条件:
実行例:
see: ポーカー - Wikipedia
1 reply [ reply ]