【问题标题】:Checking Poker Hands检查扑克手
【发布时间】:2014-01-01 22:59:35
【问题描述】:

我在检查扑克牌时遇到了一些问题。所以在这段代码中,我们选择了我们想要玩多少副牌,然后剩下的就像视频扑克一样。我的问题是一些被检查的手是“看到的”。直截了当,我假设因为我将它设置为好像我的数组列表是按假设排序的,我将如何解决这个问题?

另外,对于两对,我的朋友说有几次它不会正确检查我是否真的有两对,说它没有正确检查。这是我的检查算法,谁能告诉我如何解决它们?此外,如果您看到除了顺子和两对有问题之外的任何问题。我还没有打满屋子或更大还没有测试。 .get(#) 从我的手 (arraylist) 中获取卡片套装或等级 (getsuit 或 getrank)。我也认为我的皇家同花顺可能不正确。

private boolean flush(){
        if (currentHand.get(0).getSuit() == currentHand.get(1).getSuit()
                && currentHand.get(1).getSuit() == currentHand.get(2).getSuit()
                && currentHand.get(2).getSuit() == currentHand.get(3).getSuit()
                && currentHand.get(3).getSuit() == currentHand.get(4).getSuit()){
        return true;
        }
        return false;
    }

    private boolean royal(){

            if ((currentHand.get(0).getRank() == 1)
                    && (currentHand.get(1).getRank() == 10)
                    && (currentHand.get(2).getRank() == 11)
                    && (currentHand.get(3).getRank() == 12)
                    && (currentHand.get(4).getRank() == 13)) {

                return true;

            }
        return false;
    }
    private boolean straight(){//look up
        if (currentHand.get(0).getRank() + 1 == currentHand.get(1).getRank()
                    && currentHand.get(1).getRank() + 1 == currentHand.get(2).getRank()
                    && currentHand.get(2).getRank() + 1 == currentHand.get(3).getRank()
                    && currentHand.get(3).getRank() + 1 == currentHand.get(4).getRank()) {

        return true;
        }
        return false;

    }
    private boolean four(){
        if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
                && currentHand.get(1).getRank() == currentHand.get(2).getRank()
                && currentHand.get(2).getRank() == currentHand.get(3).getRank()) {
            return true;
        } else if (currentHand.get(1).getRank() == currentHand.get(2).getRank()
                && currentHand.get(2).getRank() == currentHand.get(3).getRank()
                && currentHand.get(3).getRank() == currentHand.get(4).getRank()) {
            return true;
        }
        return false;

    }
    private boolean fullHouse() {
        if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
                && currentHand.get(1).getRank() == currentHand.get(2).getRank()) {
            if (currentHand.get(3).getRank() == currentHand.get(4).getRank()) {

                return true;
            }


        }else if(currentHand.get(0).getRank() == currentHand.get(1).getRank()){
            if(currentHand.get(2).getRank() == currentHand.get(3).getRank()
                && currentHand.get(3).getRank() == currentHand.get(4).getRank()){
                return true;
            }

        }
        return false;
    }
    private boolean threeOfKind(){
        if ((currentHand.get(0).getRank() == currentHand.get(1).getRank()
                && currentHand.get(1).getRank() == currentHand.get(2).getRank())
                || (currentHand.get(1).getRank() == currentHand.get(2).getRank()
                && currentHand.get(2).getRank() == currentHand.get(3).getRank())
                || (currentHand.get(2).getRank() == currentHand.get(3).getRank()
                && currentHand.get(3).getRank() == currentHand.get(4).getRank())){
        return true;
        }
        return false;
    }
    private boolean twoPair() {
        if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
                && currentHand.get(2).getRank() == currentHand.get(3).getRank()){
            return true;
        }


            else if((currentHand.get(1).getRank() == currentHand.get(2).getRank())&&
            (currentHand.get(3).getRank() == currentHand.get(4).getRank())){
                return true;
            }

           else if((currentHand.get(0).getRank() == currentHand.get(1).getRank())&&
            (currentHand.get(3).getRank() == currentHand.get(4).getRank())){
                return true;
            }else

        return false;
    }
    private boolean jackOrBetter() {
        for (int i = 11; i <= 14; i++) {
            int comp;
            if (i == 14)
                comp =1;
            else comp = i;
            for (int j = 0; j < 4; j++) {
                if (currentHand.get(j).getRank() ==comp ) {
                    if (currentHand.get(j).getRank() == currentHand.get(j + 1).getRank()) {
                        return true;
                    }
                }
            }
        }
        return false;

【问题讨论】:

  • 这是什么语言?
  • royal() 绝对看起来不正确。例如如果您在其他卡片上也有 11、12 和 13 的值,那么 currentHand.get(0) == 10 和 currentHand(1) == 1 不会成为皇家同花顺吗?如果没有,您需要一个循环来执行此检查。

标签: java poker


【解决方案1】:

通常,您会在已知(并且速度非常快)的扑克评估器中找到的代码比这低得多:没有花哨的 OO 或类似的东西。只是简单的快速位操作和疯狂、疯狂的快速表查找。那里的快速手评估器可以评估数亿(!)手......每秒!但是,让我们把它放在一边,从您的 OOish 代码开始。

我认为您需要一个五张牌评估器,然后如果您玩德州扑克,那么您将测试 C(7,5),它给出了 21 种可能的方法来取出 5 张牌七(5 在板上 + 2 张底牌)。并保持最佳状态。

接着你的五张牌评估员。

“技巧”是通过保留中间信息来简化您的工作。然后你的逻辑就大大简化了。

这是您可以做到的一种方法(再次重申:与真正的快速评估者相比,这过于简单,但它应该可以帮助您完成工作):

final boolean isFlush = flush();
final int[] nbPerRank = findNumberForEachRank();
final boolean isStraight = straight( nbPerRank );

nbPerRank 数组的位置,例如,“皇后满五人”(三个皇后和两个五人)可能如下所示:

;                   2  3  4  5  6  7  8  9  T  J  Q  K  A  

int[] nbPerRank = [ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0 ]

那么你的 main 方法应该看起来像这样:

if ( isStraight ) {
    final int highCard = findStraightHighCard();
    if ( isFlush ) {
        if ( highCard == 13 ) {     // starting with the 'A'
            System.out.println( "You have a royal flush" );
        else if ( highCard = 4 ) {  // starting with the '5'
            System.out.println( "You have a wheel straight flush" );  
        } else {
            System.out.println( "You have a straight flush " );
        }
     } else {
        ... // rinse and repeat for normal straight
     }
 } else {
    ...

请注意,看到您的评估员是 5 张牌评估员,一旦您拿到顺子,您就会知道只有两种可能的情况:顺子和同花顺(有五张牌,如果您已经有对子,则不可能有对子这五张牌是顺子)。

所以现在你已经考虑了同花顺和顺子,你现在需要依次检查:

  • 四样
  • 满屋/船
  • 同花顺(但不再是同花顺)
  • 设置
  • 两对
  • 一对

要检查您是否有四个同类,然后查看您的 nbPerRank int 数组中是否有数字 4。

伪代码可能是这样的:

// no need to test for straight an straight flush anymore...
if ( hasFourSameRank ) {
   " You have four of a kind ";
} else if ( hasThreeSameRank && hasTwoSameRank ) {
    " You have a full house ";
} else if ( isFlush ) {
    " You have a flush";
} else if ( hasThreeSameRank ) {
    " You have a set ";
} else if ( hasTwoSameRank ) {
    // two possible cases here: two pairs or one pair
    if ( hasTwoPairs ) {
        "You have two pairs";
    } else {
        "You have one pair";
} else {
    "You have no pair";
}

嵌套的 if / else 在此类评估器中非常正常(至少那些不使用查找表 / LUT 的评估器)。

请注意,这只是一种方法。您可以“更高级”,而不是简单地返回一个包含每个等级的每张卡片数量的 int[],您还可以返回最大卡片、相似等级的最大数量等。

然后,您必须找到一种方法为每手牌分配一个值(因此称为“评估者”名称),以便 “两对,8 和 2,踢球者杰克” 击败 “两对,8s 和 deuces,kicker 9”等。

但这应该让你开始。

另一种解决方案是简单地重用现有的评估器之一(除了经过试验和测试之外,它应该非常快:它只是位操作和查找表,没有缓慢的 OO)。

(稍微相关)您可能还想在这里阅读我的旧答案: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?

【讨论】:

  • 也许你的意思是 if ( highCard == 13 ) 而不是 if ( highCard = 13 ),对于 = 4 也是如此。
  • @MarcoLopezAcierno:是的,谢谢,已编辑。我还认为他的牌是基于 1 而不是基于 0(因为在他的问题 OP 中他使用基于 1 而不是基于 0),这就是为什么我的示例中的 A 是 13 而不是 12。
  • 你想把按位运算放在哪里?根本没有任何操作。
  • 对于查找表,在我看来,您需要构造查找值的时间与检查手牌的时间相同。
猜你喜欢
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多