最简单的扑克手牌评估算法
2022-09-01 13:43:13
我正在考虑扑克手(5张牌)评估。现在我正在寻找简单和清晰,而不是性能和效率。我可能可以写一个“幼稚”的算法,但它需要大量的代码。Java
我还看到了一些扑克评估库,它们使用哈希和按位运算,但它们看起来相当复杂。
什么是“最干净,最简单”的扑克手牌评估算法?
我正在考虑扑克手(5张牌)评估。现在我正在寻找简单和清晰,而不是性能和效率。我可能可以写一个“幼稚”的算法,但它需要大量的代码。Java
我还看到了一些扑克评估库,它们使用哈希和按位运算,但它们看起来相当复杂。
什么是“最干净,最简单”的扑克手牌评估算法?
这是Python中一个非常短但完整的直方图,基于5张牌扑克评分函数(2.x)。如果转换为Java,它将变得相当长。
def poker(hands):
scores = [(i, score(hand.split())) for i, hand in enumerate(hands)]
winner = sorted(scores , key=lambda x:x[1])[-1][0]
return hands[winner]
def score(hand):
ranks = '23456789TJQKA'
rcounts = {ranks.find(r): ''.join(hand).count(r) for r, _ in hand}.items()
score, ranks = zip(*sorted((cnt, rank) for rank, cnt in rcounts)[::-1])
if len(score) == 5:
if ranks[0:2] == (12, 3): #adjust if 5 high straight
ranks = (3, 2, 1, 0, -1)
straight = ranks[0] - ranks[4] == 4
flush = len({suit for _, suit in hand}) == 1
'''no pair, straight, flush, or straight flush'''
score = ([1, (3,1,1,1)], [(3,1,1,2), (5,)])[flush][straight]
return score, ranks
>>> poker(['8C TS KC 9H 4S', '7D 2S 5D 3S AC', '8C AD 8D AC 9C', '7C 5H 8D TD KS'])
'8C AD 8D AC 9C'
查找表是解决问题的最直接和最简单的解决方案,也是最快的解决方案。诀窍是管理表的大小,并保持使用模式足够简单,以便非常快速地处理(空间 - 时间权衡)。显然,从理论上讲,你可以对每只手进行编码,并有一系列评估,然后 - 噗 - 一个表格查找,你就完成了。不幸的是,对于大多数机器来说,这样的表将是巨大且难以管理的,并且随着内存被大量交换,您总是会摔碎磁盘。
所谓的二加二解决方案是一张10M的大桌子,但实际上涉及一张桌子查找手中的每张牌。您不太可能找到更快,更简单易懂的算法。
其他解决方案涉及具有更复杂索引的更压缩表,但它们易于理解且非常快(尽管比2 + 2慢得多)。在这里,您可以看到有关哈希等语言 - 将表大小减小到更易于管理的大小的技巧。
无论如何,查找解决方案比直方图排序-在头上跳舞-比较-特殊情况-顺便是齐平的解决方案快几个数量级,几乎没有一个值得再看一眼。