扑克牌 - 确定F#中的满堂红

时间:2016-12-09 11:57:24

标签: f# poker

如果有三种类型的话,我的fullHouse函数的问题是真的。 该函数检查3种类型和一对但它满足逻辑只有三种(D,Ace)(C,Ace)(S,Ace)(D,Ten)(D,9)。这不是一个完整的房子,但它允许相同的3个ace同时满足一对和三个。

如何限制这一点,以便它不能将3种减少为一对?

谢谢!

编辑:F#新手

EDIT_2:一个满堂红的是当你手中拿出5张牌时你有3张同样值(3件相同值(套装无关紧要,但必须是3倍A或3倍数等))和一对(2x 10's,2x 8's等等 - 套装并不重要)

输入:

fullHouse [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;

预期输出:错误, 实际输出:真

输入:

fullHouse [(D, K);(C, K);(S, K);(D, T);(C, T)];;

预期输出:是的, 实际输出:真

1 个答案:

答案 0 :(得分:9)

My take on this would be to handle all the cases of Four of a Kind, Full House, Triple, Pair or none of the above all together.

To do this, I would use List.groupBy in order to group by card values. This will give you a list of lists of each group of the same card value. For example:

[(D, K);(C, K);(S, K);(D, T);(D, V 9)] |> List.groupBy (snd);;

Gives the result:

[(K, [(D, K); (C, K); (S, K)]); (T, [(D, T)]); (V 9, [(D, V 9)])]

i.e. A list of three Kings, a list of one Ten and a list of one Nine.

Now you just need to make sure the longest sublists appear at the start for convenient pattern matching, so simply order this list by the number of cards contained in each sublist and then you can pattern match against the hand to obtain the result.

let (|FourOfKind|FullHouse|Triple|Pair|Other|) hand =
    let groups = hand |> List.groupBy (snd) |> List.sortByDescending (List.length << snd)
    match groups with
    |(v, [c1; c2; c3; c4]) :: rest -> FourOfKind (c1, c2, c3, c4)
    |(v, [c1; c2; c3]) :: (v2, [c4; c5]) :: rest -> FullHouse(c1, c2, c3, c4, c5)
    |(v, [c1; c2; c3]) :: rest -> Triple(c1, c2, c3)
    |(v, [c1; c2]) :: rest -> Pair(c1, c2)
    |_ -> Other

You could then do, e.g.

let printHand = function
    |FourOfKind _ -> printfn "Four of a Kind"
    |FullHouse _ -> printfn "Full House"
    |Triple _ -> printfn "Triple"
    |Pair _ -> printfn "Pair"
    |Other -> printfn "Other"

Then in fsi:

printHand [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;
Triple

printHand [(D, K);(C, K);(S, K);(D, T);(C, T)];;
Full House