最简单的扑克手评估算法

新手上路,请多包涵

我正在考虑 Java 中的扑克牌手(5 张牌)评估。现在我正在寻找简单性和清晰性,而不是性能和效率。我可能可以编写一个“天真的”算法,但它需要大量代码。

我还看到了一些扑克评估库,它们使用哈希和位运算,但它们看起来很复杂。

什么是“最干净、最简单”的扑克牌评估算法?

原文由 Michael 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 384
2 个回答

这是 Python (2.x) 中一个非常简短但完整的基于直方图的 5 张扑克牌计分函数。如果转换为 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'

原文由 dansalmo 发布,翻译遵循 CC BY-SA 3.0 许可协议

查找表是该问题最直接、最简单的解决方案,也是最快的。诀窍是管理表的大小并保持使用模式足够简单以便快速处理( 时空权衡)。显然,从理论上讲,您可以只对每只可以握住的手进行编码并进行一系列评估,然后 –poof– 一个表查找就完成了。不幸的是,对于大多数机器来说,这样的表将是巨大的且难以管理的,并且随着内存被大量交换,您总是会不停地抖动磁盘。

所谓的二加二解决方案拥有一张 10M 的大表,但字面意思是为手中的每张牌进行一次表查找。您不太可能找到更快、更易于理解的算法。

其他解决方案涉及具有更复杂索引的更多压缩表,但它们很容易理解并且非常快(尽管比 2+2 慢得多)。在这里您可以看到有关散列等的语言——将表大小减小到更易于管理的大小的技巧。

在任何情况下,查找解决方案都比直方图排序舞蹈在你的头上比较特殊情况和顺便说一下是冲洗解决方案快几个数量级,几乎没有其中值得再看一眼。

原文由 wizardwerdna 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题