(免责声明:我写了一个非常快速的扑克牌评估器)
我想枚举/循环所有 48 个,选择 5 个可能的
棋盘组合并计算玩家 A 获胜的次数和次数
玩家 B 获胜,当双方平局时。
您不想每次在翻牌前两个玩家之间进行对决时都评估 C(48,5) (1 712 304) 手牌:大多数程序只是在翻牌前两个玩家之间的所有可能对决之间使用预先计算的查找表。
例如,假设您有“Ac Ad”与“7c 6c”,您只需查看包含以下内容的查找表:1 333 573, 371 831, 6900
(其中 1 333 573 是“Ac Ad”获胜的次数,371 831 是“7c 6c”获胜的次数,6 900 是平局的次数(它们的总和为 1 712 304)。要获得一些空间,您可以可以丢弃 6 900,因为知道平局数始终为C(48,5) - (胜 1 + 胜 2).
(更多关于本答案末尾的查找表)
但回答你的问题:
我不知道如何系统地循环浏览每 5 张卡片
组合。
如果您确实想循环遍历每个组合,您必须知道扑克牌评估器通常是那种需要非常非常快的程序。这些程序通常可以每秒评估数亿次手(您没看错:数亿次)。
当您需要如此高性能的“数字运算”时,您可以忘记“设计模式”和“面向对象”。你想要的是原始速度。
例如,下面的代码将通过最内层循环 C(48,5) 次,而且速度相当快:
for ( int i = 0; i < n; i++ ) {
for ( int j = i + 1; j < n; j++ ) {
for ( int k = j + 1; k < n; k++ ) {
for (int l = k + 1; l < n; l++) {
for (int m = l + 1; m < n; m++) {
...
}
}
}
}
}
对于翻牌前的两名玩家来说,这可能是一个非常糟糕的主意:使用查找表你会更快。
但是对于翻牌前的三名玩家(使用翻前牌桌是不切实际的,有太多的对局),您可能想要像这样循环,在 C(46,5) 手牌上,使用五个嵌套循环(当然您需要使用 i,j,k,l,m 从剩下的 46 张牌中取出正确的 5 张牌)。然后,一旦你拿到了 5 张牌,你就可以使用快速手牌评估器,为你提供 7 张牌中最好的一张(牌面的 5 张牌 + 每个玩家的两张牌)。
关于查找表:
大多数人使用近似的 169 vs 169 查找表(“Ac Kd”、“As Kh”、“Ad Ks”等全部变成“AK 非同花”,并且 C(52,2) 可能的起手牌被分组为 169 类型起手牌数)。维基百科文章解释了如何获得 169 张非等值起手牌:
http://en.wikipedia.org/wiki/Texas_hold_%27em_starting_hands http://en.wikipedia.org/wiki/Texas_hold_%27em_starting_hands
当你采取时它们是不等价的one手考虑,但一旦你这样做手牌 1 VS 手牌 2“169 vs 169”是一个近似值(这是一个很好的近似值)。
当然,你可以变得更喜欢。只有 C(52,2)(给出 1326)种真正不同的德州扑克起手牌,这意味着在现代计算机上构建完美的查找表(根本没有近似值)非常实用(C(1326,2) ain没那么大)如果你真的需要完美的数字。如果您可以接受近似值,请使用 169 与 169 表(它需要 C(169,2) 或 14 196 个条目)。