【问题标题】:On Two Plus Two poker hand evaluator, how do you get the best 5 cards combination out of the 7 that you passed to it?在二加二扑克手牌评估器中,您如何从传递给它的 7 张牌中获得最好的 5 张牌组合?
【发布时间】:2012-03-29 23:46:21
【问题描述】:

是否可以从等价值中提取该信息?

我知道等价值越高越好。类别和等级也可以从等价值中提取。但是有没有办法从你传递给它的 7 张牌中找出最好的 5 张牌组合?

Twoplustwo 是最快的扑克手牌评估器(每秒评估 14-1500 万手牌)。你给它 7 张牌,它会吐出一个手等值值。数值越高,卡越好。

这里有一个关于twoplustwo的精彩总结:http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup#2p2

以上链接的缓存版本: http://web.archive.org/web/20130116102452/http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup

【问题讨论】:

  • 你能详细说明什么是二加二扑克牌手评估吗?
  • 您好,templatetypedef,我已经用 twoplustwo 的链接更新了问题。
  • 还是不明白。 7张牌中最好的5张牌?或者别的什么。
  • 链接指向一个停放的域。虽然这个问题已经 4 年了,但它仍然首先显示了我的 Google 搜索。
  • 刚刚偶然发现了这个问题。 Coding the Wheel 是我的旧博客。这些天没有做太多的扑克工作,但 2+2 评估器仍然是我最喜欢的算法/实现之一,它是由 2+2 论坛 IIRC 上的一群名字如“JukOfYork”的人发明的。更简单的时间... =)

标签: algorithm poker


【解决方案1】:

(免责声明:我正在开发一款扑克软件,其中包括手牌评估)

你把你的 7 张牌给它,它会吐出一个手牌等值值。

有几位评估员这样做,如果我没记错的话,他们中的一些人每秒计算超过一亿手(!)。这些评估器基本上可以在一个巨大的数组中进行 7 次数组查找,并且只需要几个周期(尽管缓存未命中)来评估一手牌。我不认为 14-15 百万/秒是最快的。如果我没记错的话,CactusKev 的评估器快 10 倍。

现在回答你的问题:

你如何从你的 7 张牌中得到最好的 5 张牌组合 传给它?

它不会告诉你但是一旦你掌握了手的力量,它就会变得非常容易:你不需要重新发明轮子。

您可以利用强度来简化“七分之五”的计算。

也可以使用其他库,直接给您最好的五张牌(而不仅仅是他们的强度),或者您可以使用强度自己找到五张最佳牌。

我只举几个例子……

  • 您知道您有满堂彩(a.k.a.“船”),然后您知道您正在寻找具有相同等级的三张牌,然后是最佳对子(如果有两对,但你肯定会找到至少一对,因为评估员告诉你你有一条船)。

  • 你知道你有顺子:从最好的一张开始,找出五张彼此跟随的牌(小心特殊的轮盘盒)。

    您还可以对顺子更感兴趣:您可以将每个可能的顺子的力量与这些力量进行比较。如果它匹配,比如说,一个 10 高的顺子,那么只需寻找任何 T、9、8、7 和 6 牌(无论花色如何)。

  • 你知道你没有“对子”:只需拿你找到的最高的五张牌

只有几个不同的等级......例如,它们可能是:

NO_PAIR
ONE_PAIR
TWO_PAIRS
SET
STRAIGHT
FLUSH
FULL_HOUSE
FOUR_OF_A_KIND
STRAIGHT_FLUSH

(如果需要,您当然可以创建中间“直轮”、“直轮”和“皇家同花顺”案例等)

一旦您知道自己的手是哪种类型的手(感谢您使用的快速评估器),只需切换到一段代码,即可在该特定手的七种中找到最佳的五种。

我认为这是一个很好的方法,因为您可以利用超快速评估器,然后大大简化您的逻辑。

在启动时,您需要计算一次强度,例如通过计算:

HIGHEST_NO_PAIR_HAND = ultraFastEvaluator( "As Kd Qh Jc 9d 5s 2c" );

HIGHEST_FULL_HOUSE = ultraFastEvaluator( "As Ac Ad Kh Ks 8s 2h" );

我当然不提倡在这里使用字符串。这只是一个例子......

然后,您可以为每一手牌找出实际最好的五手牌:

  • 使用快速评估器计算强度
  • 是的:拿五张最高牌
  • 不:是

因此,在我看来,您可以重用一个 API,该 API 可以直接从 7 个中找出最好的 5 个,或者完全重写您自己的 API,但如果您使用快速评估器的结果来简化您的逻辑。

编辑请注意,不一定有一种方法可以做到“七分之五”。例如,在 Kc Kd Qh Qs 2c 的公共牌上使用 As Ac,“As Ac Kc Kd Qh”和“As Ac Kc Kd Qs”都是“五强”(最后一个后的花色无关紧要)。

【讨论】:

  • 我认为你错了。可用的 Cactus Kev 评估器仅处理 5 张牌。我仍在尝试找出目前最快的 7 卡评估器。
【解决方案2】:

不,无法提取该信息。查找表仅包含等价值,这些值分为手型和等级;没有其他信息被保留。

如果您需要每秒评估数百万手牌并获得每手牌的获胜手牌,而不仅仅是排名,您将需要使用不同的评估器。如果您只需要很少提取获胜手牌,您可以使用此评估器,并在必要时使用较慢的方法来找到最好的 5 张牌。

【讨论】:

  • 谢谢尼克!关于使用什么评估器来提取获胜手牌有什么建议吗?
  • @ian 恐怕不是。一个相当幼稚的人可以完成这项工作,但我没有具体的建议。
  • @Nick Johnson:(查看我的分析器)...我在自己的扑克软件中做了什么(我在不需要的地方进行了很多评估知道最好的五分,然后,很少,实际上需要最好的五分之一),是重用快速手评估器的结果,然后简化用于从七分之一中找到最佳五分的方法(见我的回答)。它当然更慢,但从我的测试来看,它比从头开始重新编写完整的“七分之五”更快(也更容易,尽管也许有点冗长)。 :)
【解决方案3】:

旧帖子,但我会试一试。如果您正在使用表格查找(例如,上面提到的 7 卡数组,也称为 Ray Wotton 方法),请在相同的插槽位置构建带有目标信息的第二个表格。示例:我最终在插槽 167,452 中找到了我的 eval,现在我将查看插槽 167,452 中的另一个数组以找到我的 5 张牌。

一张牌可以用 6 位表示 - 2 位表示花色,4 位表示等级。 30 位将给你整个 5 张牌。也许不是那么简单,但这是一般的想法。我在不久前做过的一些事情上使用了这种精确的技术。

或者,您可以传递所有 7-choose-5-card 组合(我相信有 21 个)并找出与原始 eval 匹配的组合。

【讨论】:

    【解决方案4】:

    twoplustwo 手牌评估器可以评估五张牌手。这是 C# 中的代码:

    int LookupFiveCardHand(int[] cards) {
        //assert cards size is 5
        int p = HR[53 + cards[i++]];
        p = HR[p + cards[i++]];
        p = HR[p + cards[i++]];
        p = HR[p + cards[i++]];
        p = HR[p + cards[i++]];
        return HR[p];
    }
    

    请注意,尽管有 5 张卡片,但仍有 6 次数组查找。

    无论如何,由于评估器速度如此之快,您可以比较每一种可能的 5 卡组合。包含 7 张牌的手牌将有 21 个 5 牌组合。 C# 中的代码:

    List<int> GetBestFiveCards(List<int> sevenCardHand) {
        List<List<int>> fiveCardHandCombos = new List<List<int>>();
    
        // adds all combinations of five cards to fiveCardHandCombos
        for (int i = 0; i < sevenCardHand.Count; i++) {
            for (int j = i+1; j < sevenCardHand.Count; j++) {
                List<int> fiveCardCombo = new List<int>(sevenCardHand);
                fiveCardHandCombos.RemoveAt(j); // j > i, so remove j first
                fiveCardHandCombos.RemoveAt(i);
                fiveCardHandCombos.Add(fiveCardCombo);
            }
        }
    
        Dictionary<List<int>, int> comboToValue = new Dictionary<List<int>, int>();
        for (int i = 0; i < fiveCardHandCombos.Count; i++) {
            comboToValue.Add(fiveCardHandCombos[i], LookupFiveCardHand(fiveCardHandCombos[i]));
        }
        int maxValue = comboToValue.Values.Max();
        return comboToValue.Where(x => x.Value == maxValue).Select(x => x.Key).First(); //grab only the first combo in the event there is a tie
    }
    

    【讨论】:

    • fiveCardHandCombos.RemoveAt(j); // j > i, 所以删除前五个CardHandCombos.RemoveAt(i);应该更改为 FiveCardCombo
    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2017-07-11
    相关资源
    最近更新 更多