Checking Poker Hands

瘦欲@ 提交于 2019-12-11 06:38:59

问题


I been having some issues checking poker hands. So in this code we choose how many decks we want to play with and then the rest is like video poker. My issue is that some of the hands checked are "seen". For the straight, I assume because I have it set as though my arraylist is sorted by assumption, how would I fix that?

Also, for two pair, my friend said that a few times it would not properly check if I actually had the two pair, saying it wasn't checking correctly. Here are my check algorithms, can anyone tell me how to fix them? Also, if there are any problems you see besides the straight and two pair having issues. I haven't hit full house or greater yet to test. The .get(#) gets the card suit or rank (getsuit or getrank) from my hand (arraylist). I also think my royal flush may be incorrect.

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;

回答1:


Typically the kind of code you'll find in the known (and very fast) poker evaluators are much lower-level than that: no fancy OO or anything like that. Just plain fast bit manipulation and crazy, crazy fast table lookups. The fast hand evaluators out there can evaluate hundreds of millions (!) of hands... Per second! But let's leave that aside and start from your OOish code.

I take it you want a five cards evaluator and then if you play, say, Texas Hold'em then you're going to test the C(7,5), which gives 21, possible ways to take 5 cards out of seven (5 on the board + 2 holecards). And keep the best hand.

So on to your five-cards evaluator.

A "trick" is simplify your job by keeping intermediate information. Your logic is then greatly simplified.

Here's one way you could do it (once again: this is an over-simplification compared to real fast evaluators but it should help you get the job done):

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

Where the nbPerRank array for, say, "Queens full of five" (three queens and two fives) may look like this:

;                   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 ]

Then your main method shall look a bit like this:

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 {
    ...

Note that seen that your evaluator is a 5 card evaluator, once you have a straight you know there are only two possible cases: straight and straight flush (with five cards, it is impossible to have even a pair if you already have a straight with these five cards).

So by now you already have taken the straight flush and the straight into account, you now need to check, in order, for :

  • four of a kind
  • full house / boat
  • flush (but not straight flush anymore)
  • set
  • two pairs
  • one pair

To check if you have four of kind you then see if you have the number 4 in your nbPerRank int array.

Pseudo-code could be like this:

// 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";
}

The nested if / else are quite normal in such evaluators (at least the ones not using lookup tables / LUT).

Note that this is just one way to do it. You can go "fancier" and instead of returning simply an int[] containing the number of each card per rank you can also return the max card, the max number of similar rank, etc.

You'll then have to find a way to assign a value (hence the "evaluator" name) for each hand, so that "two pairs, eights and deuces, kicker jack" beats "two pairs, eights and deuces, kicker nine" etc.

But this should get you started.

Another solution would be to simply reuse one of the existing evaluator out there (which, in addition to be tried and tested, shall be really fast: it's only bit manipulation and lookup tables, no slow OO).

(slightly related) you may also want to read my old answer here: 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?



来源:https://stackoverflow.com/questions/20578974/checking-poker-hands

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!