Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Make a poker hand evalutator in Java

5.00/5 (3 votes)
8 Aug 2009CPOL14 min read 163.2K  
Creates, evalutates, and compares 5-card poker hands.

Introduction

The title says it all: make a program that can create, evaluate, and compare 5-card poker hands.

Background

This tutorial works fine as a stand-alone, but if you want some more information about creating the deck and card class in Java, see here.

Using the code

This program will be able to generate, evaluate, and compare poker hands. A basic understanding of OO design is required (making classes, and having them interact with one another). No inheritance or interfaces here. ;) Random, ArrayLists, and static variables and methods are used on occasions, but they won't be a show stopper if you don't know what they are yet. I include quick descriptions in the For beginners: notes.

So what do we need in OO poker? We have cards, decks, and hands. Card will be a class that contains rank and suit variables, Deck will be a container for Cards, and Hand will be where we evaluate and compare the poker hands.

Java
package javapoker;
public class Card{
    private short rank, suit;

    private static String[] suits = { "hearts""spades""diamonds""clubs" };
    private static String[] ranks  = { "Ace""2""3""4""5""6""7""8""9""10""Jack""Queen""King" };

    public static String rankAsString( int __rank ) {
        return ranks[__rank];
    }

    Card(short suit, short rank)
    {
        this.rank=rank;
        this.suit=suit;
    }

    public @Override String toString()
    {
          return ranks[rank] + " of " + suits[suit];
    }

    public short getRank() {
         return rank;
    }

    public short getSuit() {
        return suit;
    }
}

So we have read-only suit and rank variables, a simple constructor, a toString method, and a rankAsString method. The class will be ultra fast as it knows which strings to output just by accessing indexes of static arrays. This array functions as a dictionary, allowing us to convert an int to the appropriate string quickly and easily. We don't even have to use String.ParseInt(). We could've made a switch statement that would find the appropriate string to output based on the suit and rank variables, but it would have to evaluate them every time. Accessing an array at a specific index is much faster. The rankAsString method is a utility method for taking a number and turning it into the appropriate string for the rank (we'll use it later).

For beginners: Notes on the static keyword: static methods and variables apply to a class as a whole, not any particular instance like instance methods and variables. We call getRank() on a specific card instance, created with new. But we would call rankAsString on the class, with "Card.rankAsString( 4 );". We have a static array to represent the different names of the suits. This array belongs to the class as a whole, not just one Card, so it can be accessed by the instance methods of each Card, and by the static methods of the class.

Note: Now, we could've used short or even byte for the rank and suit variables, since there are only four possible values. But computers work much faster with 4 byte ints than 2 byte shorts, so what would be lost in extremely tiny bits of memory you'll gain in processing speed. Using ints instead of shorts is best practice in Java.

Now we need a deck to hold our cards. I've made another tutorial showing many different ways of making a deck, but in this tutorial, I'll just show the most efficient way.

Java
package javapoker;
import java.util.Random;import java.util.ArrayList;
public class Deck {
    private ArrayList<Card> cards;

    Deck()
    {
        cards = new ArrayList<Card>();
        int index_1, index_2;
        Random generator = new Random();
        Card temp;

        for (int a=1; a<=4; a++)
        {
            for (int b=1; b<=13; b++)
             {
               cards.add( new Card(a,b) );
             }
        }

       int size       

        for (int i=0; i<100; i++)
        {
            index_1 = generator.nextInt( cards.size() - 1 );
            index_2 = generator.nextInt( cards.size() - 1 );

            temp = cards.get( index_2 );
            cards.set( index_2 , cards.get( index_1 ) );
            cards.set( index_1, temp );
        }
    }

    public Card drawFromDeck()
    {       
        return cards.remove( 0 );
    }

    public int getTotalCards()
    {
        return cards.size();
        //we could use this method when making 
        //a complete poker game to see if we needed a new deck
    }
}

We put the cards in the ArrayList of Cards, then randomly take 100 pairs of cards and switch them, shuffling our deck. To draw from the deck, we just return the first element/card, and then remove that card from the deck. All the randomization is done beforehand in the constructor (prior to any actual dealing of the cards), making our drawFromDeck method much simpler and less processor intensive.

Note for beginners: A brief tutorial of ArrayList: ArrayList is an example of a "generic" in Java. Generics are sort of like arrays because they store objects of a specific type (the type between the <>). But ArrayList is an object, not just an array, so it has neat methods to help us out. We can automatically get its size with size(), remove or add an object with remove() or add(), get and set objects like an array with get() and set(), and maybe most helpful of all, if we need more space, it will just automatically grow for us (actually just copies its items into a bigger array, but it handles all of this so we don't have to). This makes features we commonly need with data structures, like adding a new element, really easy to use (with an array, to add a new element to the end, we have to make an index variable that starts at zero; each time we add an object at that index, we increment it to put us at a fresh spot so we can add more objects; of course, we have to hope the array has enough space; you will see this technique used later). To use an ArrayList, we have to import java.util.ArrayList at the top of the source file.

Note for beginners: Summary of Random: Random is a neat little utility class we can use to generate random numbers. To use it, we import java.util.Random, then make a random with Random generator = new Random(). After we do this, we can use our Random instance "generator" to get random ints with nextInt(). If we pass an integer to nextInt(), it will give us a random integer less than that int and greater than zero. So when we call generator.nextInt( 52 );, it gives us a random number between 0 and 51 that we can use as an index in our ArrayList to swap two cards, shuffling the deck.

Okay, that wasn't so bad, we've got cards that can describe themselves as a string and a deck that can hold them in an ArrayList and deal them out. But now, we actually need to process them in a poker hand. The card holding mechanism will be similar to the deck, the bulk of the code will be in evaluating the hand's level. This is going to be pretty interesting, so bear with me.

We're going to have an array of 5 cards, and an array of 6 ints to represent the value of the hand. The first int will correlate to the type of the hand, 0 will be a high card, 1 a pair, with greater values for higher ranked hands. If we have a tie, the second value will have to determine the winner. How we find the second value will be unique to each type of hand: in a pair, the higher pair wins; in a straight, the higher top card wins, etc. If those values are equal, we move onto the next determining factor, like the highest card besides the pair, or the low pair of a two pair hand. Some hands will only have two determining factors, like a straight. The first value would be a straight's spot in the rank of the poker hands (greater than 3 of a kind, less than a flush), and the second value would be the top card in the straight (7, jack, king, etc.). For a high card, we'd have 0, as high card is the lowest ranked hand, and the next 5 values would be the ranks of the cards in the hand in descending order.

Here's what we have so far:

Java
package javapoker;
public class Hand {
    private Card[] cards;
    private int[] value;

    Hand(Deck d)
    {
        value = new int[6];
        cards = new Card[5];
        for (int x=0; x<5; x++)
        {
            cards[x] = d.drawFromDeck(); //fill up cards[] array.
        }

        //rest of our code to assign values to the value array goes here
    }
   

    void displayAll()
    {
        for (int x=0; x<5; x++)
            System.out.println(cards[x]); //calls cards[x].toString()
    }

    int compareTo(Hand that)
    {
        for (int x=0; x<6; x++) //cycle through values
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0//if hands are equal
    }
}

All righty, now with the dirty work, figuring out the actual value of our poker hand. Let's start with a pair situation. How would we figure out if there is a pair? If we have two cards of the same rank. How will we implement this? We could cycle through the ranks, seeing if any of the ranks has two cards with its value. But then, for 3 of a kind, we'd have to do the same thing again. How about we make an array of ints starting at 0 with 13 slots (one for each rank), then go through the cards; with each card, we increment the appropriate index of the array. Let's see a code representation:

(All the code from this point on is put in the Hand constructor where our comment was.)

Java
int[] ranks = new int[14];

for (int x=0; x<=13; x++)
{
    ranks[x]=0; //zero the contents of the array
}

for (int x=0; x<=4; x++)
{
    ranks[ cards[x].getRank() ]++;
    //increment rank array at the index of each card's rank
}

For simplicity's sake, we've used card ranks starting at 1 for ace instead of 0 for ace. If we use 0 for ace, then we would be using 9 for 10, which is just confusing. Since our card ranks run 1-13, the first index of our array (0) will be empty.

Okay, so now, we have our array of card ranks, now we need to find if there are actually any pairs. We need to know if there is a pair, and if there is, what rank the pair is. So we make an int sameCards to record how many cards are of the same rank, and an int groupRank to hold the rank of the pair. We make an int sameCards because we may have more than two cards of the same value, maybe even 3 or 4 (hopefully not 5, unless our processor is a crooked dealer). We could've just made a bool isPair, but we want to know if there is a 3 or 4 of a kind as well.

Java
int sameCards=1;
//we know there will be at least one card of any rankint groupRank=0;
for (int x=13; x>=1; x--) //loop going from 13 to 1
{
    if ( ranks[x] > sameCards) //If more cards of rank x than sameCards 
    {
        sameCards=ranks[x];    //set sameCards to that number of cards
        groupRank=x;           //and record the rank of the cards 
    }
}

sameCards starts at 1, so if we find a rank of which there are two cards, then we record 2 in sameCards and rank (x) as groupRank. This will work fine if there's a pair, three of a kind, or four of a kind.

But wait a second, let's say we have a full house. There is a pair of kings, so we record 2 as sameCards and 13 as groupRank. But we keep going through the other ranks, and if there are 3 fives, then we overwrite sameCards with 3 since the number of cards of that rank is more than the current value of sameCards. Similar situation: we have two pairs, it records the first pair, but not the other one. We can do hands with one group of cards, but not hands with 2. We need a way to keep track of at least two different groups of cards, tracking the number of cards and the rank of each. Think about it a bit before moving on.

Note: this is definitely the most intense logic of the program, so if you don't get this at first, don't worry. The rest of the code is all a little easier, and you can come back to this part later. :)

My solution: all right, we have to keep track of two ranks of cards and how many cards are of each rank, so we'll have two variables to represent the ranks (largeGroupRank, smallGroupRank) and two to represent the number of cards that have that rank (sameCards, sameCards2).

C#
int sameCards=1,sameCards2=1;
//initialze to 1int largeGroupRank=0,smallGroupRank=0;

for (int x=13; x>=1; x--)
{
     if (ranks[x] > sameCards) 
     {
         if (sameCards != 1)
         //if sameCards was not the default value
         {
             sameCards2 = sameCards;
             smallGroupRank = largeGroupRank;
         }
         
         sameCards = ranks[x];
         largeGroupRank = x;
         
     } else if (ranks[x] > sameCards2)
     {
         sameCards2 = ranks[x];
         smallGroupRank = x;
     }
}

If ranks[x] is greater than sameCards, we assign the data there; otherwise, if it is greater than sameCards2, we assign the data there. Now, I'm sure you all saw the nested if, so I guess I might as well tell you what it is for. Say the if wasn't there: we find a pair of 8's, then we find three 5's. sameCards contains the pair of 8's, and since the three 5's is more than the two 8's, we overwrite sameCards. But the pair we found earlier is just overwritten and not recorded anywhere, when it should have been stuck into sameCards2. So, the if statement checks if sameCards was previously assigned to something before overwriting it, and if it was, we take care of that.

Sample run: We find 2 queens, so we record that value in sameCards, since 2 is more than the 1 we initialized sameCards with. Then, we find 2 7's, so we record that in sameCards2. We find 3 Jacks, record those in sameCards, then find 2 threes, so we record them in sameCards2. Two 8's, then three 4's. We write the data from the two 8's into sameCards2, then put the data from the three 4's into sameCards1. All is well :).

There's a little more to go, but you've made it over the hill; the rest of the code is all downhill from here.

Woo hoo! We've written the code to determine a pair, 2 pairs, three of a kind, four of a kind, and a full house. The determinations left to do is whether we have a flush or a straight.

Let's do a flush first. How do we find out if all the cards are the same suit? Well, if two cards are not the same suit, then there's no flush, so let's try this. We hitch a ride on the loop that iterates through the cards recording their ranks:

Java
boolean flush=true; //assume there is a flush
for (int x=0; x<4; x++) 
{
    if ( cards[x].getSuit() != cards[x+1].getSuit() ) 
        flush=false;
}

Okey dokey, travel through the cards, and if one of their suits doesn't match the suit of the next card, then there' no flush.

To figure out if there's a straight, we need to know if there are five cards in a row. So, if there is one card in five5 consecutive ranks, we have a straight.

Java
int topStraightValue=0;boolean straight=false;  //assume no straight  
for (int x=1; x<=9; x++) //can't have straight with lowest value of more than 10
{
    if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 && 
        ranks[x+3]==1 && ranks[x+4]==1)
    {
        straight=true;
        topStraightValue=x+4; //4 above bottom value
        break;
    }
}

if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 && 
    ranks[13]==1 && ranks[1]==1) //ace high
{
    straight=true;
    topStraightValue=14; //higher than king
}

We check to see if there is one card of 5 consecutive ranks. There's a loop to do straights up to king high, and we add a special separate if for an ace high straight, since the number of aces is contained in ranks[1].

Yay, we've covered all the different types of hands! Now, we need to start comparing them. We have what we need to determine the type of the hand, but we still need a little more data to fix ties between hands. Say we have a pair, we know that a pair is the second lowest ranked hand. If the hand we're comparing it to is also a pair, then we need to compare the rank of the pair. If the rank of the pair is equal, we need to go to the next highest card, then the next highest card, and then the next highest card. The only thing we need now is the next highest cards in order.

Java
int[] orderedRanks = new int[5];
int index=0;


if (ranks[1]==1) //if ace, run this before because ace is highest card
{
    //record an ace as 14 instead of one, as its the highest card
    orderedRanks[index]=14;
    index++; //increment position
}

for (int x=13; x>=2; x--)
{
    if (ranks[x]==1)
    //we have already written code to handle the case
    //of their being two cards of the same rank
    {
        orderedRanks[index]=x; 
        index++;
    }
}

Now we have an array that will hold all the miscellaneous cards that don't mean anything else. (w00t!)

In our Hand class, we have a private array value that holds six ints. We are going to use this to contain the values of the hands. This array will hold all the data necessary to compare two poker hands. I mentioned our process of comparing before: "Say we have a pair, we know that a pair is the second lowest ranked hand. If the hand we're comparing it to is also a pair, then we need to compare the rank of the pair. If the rank of the pair is equal, we need to go to the next highest card, then the next highest card, and then the next highest card."

This sets up a list of the things we need to compare. The most important thing is what kind of hand, so that will go in the first position. The rest of the positions will hold the data needed to break a tie between two hands of the same type. Take a look:

Java
//start hand evaluation
if ( sameCards==1 ) {    //if we have no pair...
    value[0]=1;          //this is the lowest type of hand, so it gets the lowest value
    value[1]=orderedRanks[0];  //the first determining factor is the highest card,
    value[2]=orderedRanks[1];  //then the next highest card,
    value[3]=orderedRanks[2];  //and so on
    value[4]=orderedRanks[3];
    value[5]=orderedRanks[4];
}

if (sameCards==2 && sameCards2==1) //if 1 pair
{
    value[0]=2;                //pair ranked higher than high card
    value[1]=largeGroupRank;   //rank of pair
    value[2]=orderedRanks[0];  //next highest cards.
    value[3]=orderedRanks[1];
    value[4]=orderedRanks[2];
}

if (sameCards==2 && sameCards2==2) //two pair
{
    value[0]=3;
    //rank of greater pair
    value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
    //rank of smaller pair
    value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
    value[3]=orderedRanks[0];  //extra card
}

if (sameCards==3 && sameCards2!=2)
//three of a kind (not full house)
{
    value[0]=4;
    value[1]= largeGroupRank;
    value[2]=orderedRanks[0];
    value[3]=orderedRanks[1];
}

if (straight)
{
    value[0]=5;
    value[1]=;
    //if we have two straights, 
    //the one with the highest top cards wins
}

if (flush)   
{
    value[0]=6;
    value[1]=orderedRanks[0]; //tie determined by ranks of cards
    value[2]=orderedRanks[1];
    value[3]=orderedRanks[2];
    value[4]=orderedRanks[3];
    value[5]=orderedRanks[4];
}

if (sameCards==3 && sameCards2==2)  //full house
{
    value[0]=7;
    value[1]=largeGroupRank;
    value[2]=smallGroupRank;
}

if (sameCards==4)  //four of a kind
{
    value[0]=8;
    value[1]=largeGroupRank;
    value[2]=orderedRanks[0];
}

if (straight && flush)  //straight flush
{
    value[0]=9;
    value[1]=;
}

So now that we have all of our value array set up (that was the end of the Hand constructor), we can use this method to compare our hand to any other hand:

Java
int compareTo(Hand that)
{
    for (int x=0; x<6; x++)
    {
        if (this.value[x]>that.value[x])
            return 1;
        else if (this.value[x] != that.value[x])
        //if not greater and not equal, must be less
            return -1;
    }
    return 0//if hands are equal
}

And, we can add this method to display a summary of the hand (this is also where we use the static rankAsString method in the Card class to convert an integer to an associate card rank, e.g., 11 = "Jack").

Java
void display()
{
    String s;
    switch( value[0] )
    {
        case 1:
            s="high card";
            break;
        case 2:
            s="pair of " + Card.rankAsString(value[1]) + "\'s";
            break;
        case 3:
            s="two pair " + Card.rankAsString(value[1]) + " " + 
              Card.rankAsString(value[2]);
            break;
        case 4:
            s="three of a kind " + Card.rankAsString(value[1]) + "\'s";
            break;
        case 5:
            s=Card.rankAsString(value[1]) + " high straight";
            break;
        case 6:
            s="flush";
            break;
        case 7:
            s="full house " + Card.rankAsString(value[1]) + 
              " over " + Card.rankAsString(value[2]);
            break;
        case 8:
            s="four of a kind " + Card.rankAsString(value[1]);
            break;
        case 9:
            s="straight flush " + Card.rankAsString(value[1]) + " high";
            break;
        default:
            s="error in Hand.display: value[0] contains invalid value";
    }
    s = "                " + s;
    //this just moves the output over a little in the console 
    //so its easier to see when viewing the output
    System.out.println(s);
}

Now that that exhaustive class is done, we can write some test code and see this stuff at work. Our first main method will test the randomness of the deck we made (discussed more in the past tutorial).

Java
package javapoker

public class Main {

    public static void main(String[] args)
    {
        Deck deck= new Deck();
        Card C;

        System.out.println( deck.getTotalCards() );

       while (deck.getTotalCards()!=0 )
       {
           C = deck.drawFromDeck();
           System.out.println( C.toString() );
       }
    } 
}

OK, that looks random enough, so now, let's try making some hands and seeing what the program thinks they are ranked, and compare that to what we know they should be ranked:

Java
public static void main(String[] args)  {
     for (int i=0; i<100; i++)
     {
         Deck deck= new Deck();
         Hand hand= new Hand(deck);
         hand.display(); //show the summary of the hand, e.g. "full house"
         hand.displayAll(): //look at all the individual cards in the hand         
     }
}

All righty, last mechanism to test is the hand comparing, with a similar method:

Java
 public static void main(String[] args) {
    for (int i=0; i<20000; i++)
    {
        Deck deck= new Deck();
        Hand hand= new Hand(deck);
        Hand hand2= new Hand(deck);
        hand.display();
        hand.displayAll();
        hand2.display();
        hand2.displayAll();
        System.out.println(hand.compareTo(hand2));

    }
}

And there you have it, how to make a poker hand evaluator in Java! I hope you've enjoyed this tutorial! Please post any and all comments, questions, and suggestions! :)

Note: This tutorial only covers how to make, evaluate, and compare poker hands (which I think was enough for one tutorial). It does not actually tell how to make a full playable poker game. Making betting wouldn't be that difficult, but the AI involved for making realistic opponents is beyond this scope. This is a good basis for a poker game however, and if anyone completes the poker game with good, realistic AI and gameplay, they can go ahead and post that article on CodeProject.

The code

Here is the full code for each of the classes in the tutorial (for pasting into a compiler):

Card.java
Java
package javapoker;
public class Card{
    private short rank, suit;

    private static String[] suits = { "hearts""spades""diamonds""clubs" };
    private static String[] ranks  = { "Ace""2""3""4""5""6""7""8""9""10""Jack""Queen""King" };

    public static String rankAsString( int __rank ) {
        return ranks[__rank];
    }

    Card(short suit, short rank)
    {
        this.rank=rank;
        this.suit=suit;
    }

    public @Override String toString()
    {
          return ranks[rank] + " of " + suits[suit];
    }

    public short getRank() {
         return rank;
    }

    public short getSuit() {
        return suit;
    }
}
Deck.java
Java
package javapoker;
import java.util.Random;import java.util.ArrayList;
public class Deck {
    private ArrayList<Card> cards;

     Deck()
    {
        cards = new ArrayList<Card>();
        int index_1, index_2;
        Random generator = new Random();
        Card temp;

        for (short a=0; a<=3; a++)
        {
            for (short b=0; b<=12; b++)
             {
               cards.add( new Card(a,b) );
             }
        }

        int size = cards.size() -1;

        for (short i=0; i<100; i++)
        {
            index_1 = generator.nextInt( size );
            index_2 = generator.nextInt( size );

            temp = (Card) cards.get( index_2 );
            cards.set( index_2 , cards.get( index_1 ) );
            cards.set( index_1, temp );
        }
    }

    public Card drawFromDeck()
    {       
        return cards.remove( cards.size()-1 );
    }

    public int getTotalCards()
    {
        return cards.size();
        //we could use this method when making 
        //a complete poker game to see if we needed a new deck
    }
}
Hand.java
Java
package javapoker;
public class Hand {
    private Card[] cards;
    private int[] value;

    Hand(Deck d)
    {
        value = new int[6];
        cards = new Card[5];
        for (int x=0; x<5; x++)
        {
            cards[x] = d.drawFromDeck();
        }

        int[] ranks = new int[14];
        //miscellaneous cards that are not otherwise significant
        int[] orderedRanks = new int[5];
        boolean flush=true, straight=false;
        int sameCards=1,sameCards2=1;
        int largeGroupRank=0,smallGroupRank=0;
        int index=0;
        int topStraightValue=0;

        for (int x=0; x<=13; x++)
        {
            ranks[x]=0;
        }
        for (int x=0; x<=4; x++)
        {
            ranks[ cards[x].getRank() ]++;
        }
        for (int x=0; x<4; x++) {
            if ( cards[x].getSuit() != cards[x+1].getSuit() )
                flush=false;
        }

        for (int x=13; x>=1; x--)
        {
                 if (ranks[x] > sameCards)
                 {
                     if (sameCards != 1)
                     //if sameCards was not the default value
                     {
                         sameCards2 = sameCards;
                         smallGroupRank = largeGroupRank;
                     }

                     sameCards = ranks[x];
                     largeGroupRank = x;

                 } else if (ranks[x] > sameCards2)
                 {
                     sameCards2 = ranks[x];
                     smallGroupRank = x;
                 }
        }

        if (ranks[1]==1) //if ace, run this before because ace is highest card
        {
            orderedRanks[index]=14;
            index++;
        }

        for (int x=13; x>=2; x--)
        {
            if (ranks[x]==1)
            {
                orderedRanks[index]=x; //if ace
                index++;
            }
        }
        
        for (int x=1; x<=9; x++)
        //can't have straight with lowest value of more than 10
        {
            if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 && 
                ranks[x+3]==1 && ranks[x+4]==1)
            {
                straight=true;
                topStraightValue=x+4; //4 above bottom value
                break;
            }
        }

        if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 && 
            ranks[13]==1 && ranks[1]==1) //ace high
        {
            straight=true;
            topStraightValue=14; //higher than king
        }
        
        for (int x=0; x<=5; x++)
        {
            value[x]=0;
        }


        //start hand evaluation
        if ( sameCards==1 ) {
            value[0]=1;
            value[1]=orderedRanks[0];
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==2 && sameCards2==1)
        {
            value[0]=2;
            value[1]=largeGroupRank; //rank of pair
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
            value[4]=orderedRanks[2];
        }

        if (sameCards==2 && sameCards2==2) //two pair
        {
            value[0]=3;
            //rank of greater pair
            value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
            value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
            value[3]=orderedRanks[0];  //extra card
        }

        if (sameCards==3 && sameCards2!=2)
        {
            value[0]=4;
            value[1]= largeGroupRank;
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
        }

        if (straight && !flush)
        {
            value[0]=5;
            value[1]=;
        }

        if (flush && !straight)
        {
            value[0]=6;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==3 && sameCards2==2)
        {
            value[0]=7;
            value[1]=largeGroupRank;
            value[2]=smallGroupRank;
        }

        if (sameCards==4)
        {
            value[0]=8;
            value[1]=largeGroupRank;
            value[2]=orderedRanks[0];
        }

        if (straight && flush)
        {
            value[0]=9;
            value[1]=;
        }

    }

    void display()
    {
        String s;
        switch( value[0] )
        {

            case 1:
                s="high card";
                break;
            case 2:
                s="pair of " + Card.rankAsString(value[1]) + "\'s";
                break;
            case 3:
                s="two pair " + Card.rankAsString(value[1]) + " " + 
                                Card.rankAsString(value[2]);
                break;
            case 4:
                s="three of a kind " + Card.rankAsString(value[1]) + "\'s";
                break;
            case 5:
                s=Card.rankAsString(value[1]) + " high straight";
                break;
            case 6:
                s="flush";
                break;
            case 7:
                s="full house " + Card.rankAsString(value[1]) + " over " + 
                                  Card.rankAsString(value[2]);
                break;
            case 8:
                s="four of a kind " + Card.rankAsString(value[1]);
                break;
            case 9:
                s="straight flush " + Card.rankAsString(value[1]) + " high";
                break;
            default:
                s="error in Hand.display: value[0] contains invalid value";
        }
        s = "                " + s;
        System.out.println(s);
    }

    void displayAll()
    {
        for (int x=0; x<5; x++)
            System.out.println(cards[x]);
    }

    int compareTo(Hand that)
    {
        for (int x=0; x<6; x++)
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0//if hands are equal
    }
}

Points of interest

When I was watching this program evaluate and compare 200,000 poker hands, I really felt powerful, like I had accomplished something. I couldn't have done that in 10 years, but the computer did it in a bit more than a minute.

History

  • 8-7-09: Submitted article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)