扑克牌 - 确定 F# 中的葫芦
Poker hand - Determining a full house in F#
我的 fullHouse 函数的这个问题 = true 当有一个 three-of-a-kind 时。
该函数检查一种 3 和一对,但它只满足一种 3 的逻辑 (D, Ace)(C, Ace)(S, Ace)(D, Ten)(D, 9)。这不是葫芦,但它允许相同的 3 个 A 满足一对和同类的 3。
我如何限制它,使其不能将 3 个同类减少为一对?
谢谢!
编辑:F# 新手
EDIT_2:葫芦是指当你手上有 5 张牌时,你有 3 张相同的牌(3 张相同点数(花色无关紧要,但它们必须是 3 个 A 或3x 10 等)) 和一对(2x 10,2x 8 等 - 花色无关紧要)
输入:
fullHouse [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;
预期输出:错误,
实际输出:True
输入:
fullHouse [(D, K);(C, K);(S, K);(D, T);(C, T)];;
预期输出:真,
实际输出:True
我对此的看法是同时处理所有四人组、满堂、三人组、对子或上述 none 的所有情况。
为此,我将使用 List.groupBy
以按卡片值分组。这将为您提供每组具有相同卡值的列表列表。例如:
[(D, K);(C, K);(S, K);(D, T);(D, V 9)] |> List.groupBy (snd);;
给出结果:
[(K, [(D, K); (C, K); (S, K)]); (T, [(D, T)]); (V 9, [(D, V 9)])]
即三王榜,一十榜,一九榜。
现在你只需要确保最长的子列表出现在开头以便于模式匹配,所以只需按照每个子列表中包含的卡片数量对这个列表进行排序,然后你可以对手进行模式匹配以获得结果。
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
然后你可以这样做,例如
let printHand = function
|FourOfKind _ -> printfn "Four of a Kind"
|FullHouse _ -> printfn "Full House"
|Triple _ -> printfn "Triple"
|Pair _ -> printfn "Pair"
|Other -> printfn "Other"
然后在 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
我的 fullHouse 函数的这个问题 = true 当有一个 three-of-a-kind 时。 该函数检查一种 3 和一对,但它只满足一种 3 的逻辑 (D, Ace)(C, Ace)(S, Ace)(D, Ten)(D, 9)。这不是葫芦,但它允许相同的 3 个 A 满足一对和同类的 3。
我如何限制它,使其不能将 3 个同类减少为一对?
谢谢!
编辑:F# 新手
EDIT_2:葫芦是指当你手上有 5 张牌时,你有 3 张相同的牌(3 张相同点数(花色无关紧要,但它们必须是 3 个 A 或3x 10 等)) 和一对(2x 10,2x 8 等 - 花色无关紧要)
输入:
fullHouse [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;
预期输出:错误, 实际输出:True
输入:
fullHouse [(D, K);(C, K);(S, K);(D, T);(C, T)];;
预期输出:真, 实际输出:True
我对此的看法是同时处理所有四人组、满堂、三人组、对子或上述 none 的所有情况。
为此,我将使用 List.groupBy
以按卡片值分组。这将为您提供每组具有相同卡值的列表列表。例如:
[(D, K);(C, K);(S, K);(D, T);(D, V 9)] |> List.groupBy (snd);;
给出结果:
[(K, [(D, K); (C, K); (S, K)]); (T, [(D, T)]); (V 9, [(D, V 9)])]
即三王榜,一十榜,一九榜。
现在你只需要确保最长的子列表出现在开头以便于模式匹配,所以只需按照每个子列表中包含的卡片数量对这个列表进行排序,然后你可以对手进行模式匹配以获得结果。
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
然后你可以这样做,例如
let printHand = function
|FourOfKind _ -> printfn "Four of a Kind"
|FullHouse _ -> printfn "Full House"
|Triple _ -> printfn "Triple"
|Pair _ -> printfn "Pair"
|Other -> printfn "Other"
然后在 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