【问题标题】:Picking the best hand out of 7 cards(Poker Texas Hold'em)从 7 张牌中选出最好的牌(德州扑克)
【发布时间】:2011-05-04 03:28:47
【问题描述】:

我已经使用 C# 实现了德州扑克游戏。
我编写了诸如卡片、甲板、播放器、表格等类...
例如:

    Player player1 = new Player("player1");
    player1.Card1 = new Card(4, Symbol.Clubs, true);
    player1.Card2 = new Card(5, Symbol.Clubs, true);

    Card card1 = new Card(4, Symbol.Clubs, true);
    Card card2 = new Card(7, Symbol.Hearts, true);
    Card card3 = new Card(2, Symbol.Spades, true);
    Card card4 = new Card(4, Symbol.Diamonds, true);
    Card card5 = new Card(4, Symbol.Clubs, true);
    Card[] tableCards = {card1, card2, card3, card4, card5};

我还编写了一些评估卡片数组的方法,例如 IsFlush、IsStraight、IsPair 等。
我的问题是,如果我有 7 张牌(2 手牌,桌上的 5 张牌),我应该如何选择最佳手牌组合。
在此代码示例中,它是 {4,4,4,4,7}。

【问题讨论】:

  • 到目前为止您尝试过什么?你认为你应该如何开始找到正确的手?
  • python 的类似问题here,但最佳答案链接到通用算法。
  • 这不是排名牌的好方法。你打算用这段代码做什么?
  • 作为随机参数,您可以使用可选参数new Card(value: 7, suit: Symbol.Clubs, idontknowwhatthis: true) 真正提高代码的可读性

标签: c# algorithm oop


【解决方案1】:

不要针对 5 张牌编写代码。相反,写它一般。所以,

ContainsStraightFlush
ContainsFourOfAKind
ContainsFullHouse

等等。如果这些牌的某个子集分别是同花顺、同花顺四张等,则会吃掉一组牌并返回 true。

然后从排名最高的牌倒退到最低。如果这些方法之一返回 true,那么您可以轻松挑选出满足该条件的最佳手牌。例如在

2h Kh Qh Jh Th 9h 6c

ContainsStraightFlush 将返回 true,然后您可以选择 9h Th Jh Qh Kh 作为最佳手牌。

【讨论】:

    【解决方案2】:

    首先对卡片进行排序,这将使您更轻松地搜索最佳手牌,然后您只需比较相邻元素的相同数字或顺子的倍数即可。那么你只有一个特殊情况来寻找同花顺

    【讨论】:

      【解决方案3】:

      最简单的方法是让每张 5 张牌的收集成为可能,并抓住手牌价值。记住最好的牌。 7张牌的情况只有21种组合,所以在最优性方面并不好,但也不是很糟糕,除非你用它来研究。

      foreach (possible 5 card combination in allCards)
          bestHand = Max(bestHand, GetValue(possible));
      

      或者,您可以创建一个数组,其中每张卡片有 1 个条目,每个索引是指向包含所有 2 个卡片组合的新数组的指针,其中每个索引是所有 3 个卡片组合的数组,等等。如果您可以使用所有可能的套装和等级抽象来计算它,数据结构的总大小约为内存中的 128 MB。 2+2论坛上有c++的参考实现。

      【讨论】:

      • 这里有 2+2 线程的链接,以及其他有价值的资源:@​​987654321@ 此外,使用 Cactus-Kev 5-card evaluator 并枚举可能的 5-card 手牌结果执行对于奥马哈蒙特卡洛计算(你有 9 张卡片 + 约束)来说已经足够了。对于德州扑克来说,2+2 的实施是完美的。
      • @AlexandreC.:除了完美之外,我在所有方面都同意你的看法。通过一次更换一张牌来发牌时,它运行得更快,但对于随机手分组,Pokersource 评估器更快。需要根据您最常进行的评估类型来做出决定。
      【解决方案4】:

      不要这样写,写起来非常慢而且实际上相当麻烦(逻辑很毛茸茸)。此外,对于需要运行数亿手牌的蒙特卡洛模拟,这种方法根本站不住脚。

      有关可用技术的调查,请参阅this link。实际上,使用基于表格的比较算法比使用一大堆 if 语句的代码要简单得多。

      以上文章中介绍的大多数例程都在已经捆绑的 C# 库中可用,您可以将代码插入其中。

      [第一个高性能的原创想法是there,它使用查找表、完美哈希和一个很好的素数相乘技巧来一目了然地评估一手牌。]

      【讨论】:

      • 我怀疑 OP 更感兴趣的是了解简单的方法,而不是从扑克牌标识符中榨取最终性能。
      • @Jim:生成的代码要简单得多,而且到处都有可用的 C# 库。按照 OP 的要求编写逻辑只需几百行。编写基于表的评估器只需几十个。
      • 有趣的帖子!不知道为什么其他人考虑过这个问题的想法导致您的帖子被否决。您的调查链接已失效。但它已存档在这里:web.archive.org/web/20140625212722/http://codingthewheel.com/…
      【解决方案5】:

      创建一个卡片数组,并添加前 5 张卡片。然后,对于每张额外的牌,找出手牌中最低的牌,看看额外的牌是否更大,如果是,则交换它们。请记住,您需要找到对子、顺子和葫芦等

      【讨论】:

      • 反例:3 4 5 6 8 A 2 不会按照你的方法找到6高顺子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多