• (2 Pages)
  • +
  • 1
  • 2

How to make a poker game in java creates, evaluates, and compares 5 card poker hands. Rate Topic: ***** 1 Votes

#1 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 26 July 2009 - 05:58 AM

*
POPULAR

Salutations, this is CrazyJugglerDrummer with a tutorial on how to make a poker hand evaluator in java. 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 occasion, but they won't be a show stopper if you don't know what they are yet. I include quick descriptions in FOR BEGINNERS: notes.

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

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 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's only 4 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.


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 actually dealing of the cards), making our drawFromDeck method much simpler and less processor intensive.

NOTE FOR BEGINNERS: 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 (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 datastructures, 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 array list, we have to import java.util.ArrayList at the top of the soure 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 intereger 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 card, shuffling the deck.


Okay, that wasn't so bad, we've got cards that can describe them selves 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 2 determining factors, like a straight. The first value would be a straight's spot in the rank of 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:
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 was a pair? If we had two cards of the same rank. So how will we implement this? We could cycle through the ranks, seeing if any of the ranks had 2 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)

		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 used 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 the 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 2 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.


int sameCards=1; //we know there will be at least one card of any rank
int 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 2 cards, then we record 2 in sameCards and the 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 sec, 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 was 3 fives, then we overwrite sameCards with 3 since the number of cards of that rank was more than the current value of sameCards. Similar situation: we have two pair, 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 2 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 2 ranks of cards and how many cards are of each rank, so we'll have 2 variables to represent the ranks (largeGroupRank, smallGroupRank) and 2 to represent the number of cards that haave that rank (sameCards, sameCards2).

int sameCards=1,sameCards2=1;			//initialze to 1
int 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 its 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 its 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 ealier 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 the 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. :D




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 pair, three of a kind, four of a kind, and a full house. The determinations left to do are 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 2 cards are not the same suit, then there's no flush, so let's try this. We hitch a ride on the loop that iterated through the cards recording their ranks:

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 5 cards in a row. So if there is one card in 5 consecutive ranks, we have a straight.

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, then the next highest card. The only thing we need now is the next highest cards in order.


  int[] orderedRanks = new int[5];

int index=0;


 if (ranks[1]==1) //if ace, run this before because ace is highest card
		{
			orderedRanks[index]=14; //record an ace as 14 instead of one, as its the highest card
			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 holds all the miscellaneous cards that don't mean anything else. (w00t!)



In our hand class, we a private array value, than held 6 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, 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 to hands of the same type. Take a look:


//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;
			value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank; //rank of greater pair
			value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank; //rank of smaller pair
			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]=topStraightValue;  //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]=topStraightValue;
		}



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:


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 that static rankAsString method in the Card class to convert an integer in to associate card rank e.g. 11 = "Jack")


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

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 lets try making some hands and seeing what the program thinks they are ranked, and compare that to what we know they should be ranked:

  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:


 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! :D

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 as a tutorial on DIC. :D






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

Card.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
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 won't fit into this post, so its in the first comment.

This post has been edited by crazyjugglerdrummer: 29 July 2009 - 06:31 PM


Is This A Good Question/Topic? 5
  • +

Replies To: How to make a poker game in java

#2 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 29 July 2009 - 06:31 PM

Hand.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];
		int[] orderedRanks = new int[5];	 //miscellaneous cards that are not otherwise significant
		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;
			value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank; //rank of greater pair
			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]=topStraightValue;
		}

		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]=topStraightValue;
		}


	}
   

	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
	}
}




Was This Post Helpful? 4
  • +
  • -

#3 Woceyth  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 25-October 09

Posted 01 November 2009 - 11:25 PM

Thanks for the tutorial, but I still don't understand the pair method. If it compares a pair of 3 with a pair of king, the program makes the pair of 3 the victor. Please if someone can explain it to me. It'll be grateful.
Was This Post Helpful? 0
  • +
  • -

#4 crazyjugglerdrummer  Icon User is offline

  • GAME OVER. NERD WINS.
  • member icon

Reputation: 119
  • View blog
  • Posts: 690
  • Joined: 07-January 09

Posted 04 November 2009 - 07:35 PM

Good bug catch, thanks! :D Try this updated version, The only real change is this:

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

					 sameCards = ranks[x];
					 largeGroupRank = x;

				 }



This version has slightly better comments and a clearer control flow:

 
for (int x=13; x>=1; x--) //x is rank of cards, ranks[x] is number of cards of that rank
		{
				 if (ranks[x] > sameCards)
				 {
					 if (sameCards == 1)  //if sameCards was not assigned to already
					 {
						 largeGroupRank = x;

					 }
					 else {
						 sameCards2 = sameCards; //if sameCards was assigned to, write data from 
						 smallGroupRank = x;		  //top group to low group			   
					 }

					 

					 sameCards = ranks[x];		   //update sameCards to new greatest sameCards value in ranks

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


Was This Post Helpful? 2
  • +
  • -

#5 ShadowsEdge19  Icon User is offline

  • D.I.C Addict

Reputation: 142
  • View blog
  • Posts: 664
  • Joined: 16-January 10

Posted 15 August 2010 - 04:08 AM

This is great! I've just been trying to figure out how to evaluate player hands for my own card game and this will be immensely helpful once I figure out how to implement it into my own game structure.

The only thing I will need to change is working with a hand of 7 or 8 cards with groups of 3 and 4 cards in sets or runs as the requirement and working out what card to throw away out of the useless cards. Each set or run has to be minimum of 3 and max 4 cards in length and there has to be 2 groups for a winning hand with the remaining card with a value of 9 or less. I also have wild cards that act as any card to suit any purpose.

This post has been edited by ShadowsEdge19: 15 August 2010 - 04:14 AM

Was This Post Helpful? 0
  • +
  • -

#6 aCceSs  Icon User is offline

  • New D.I.C Head

Reputation: -19
  • View blog
  • Posts: 16
  • Joined: 04-November 10

Posted 04 November 2010 - 01:29 PM

can someone make this one more easier guide maybe with video? :-) just askin

aCceSs
Was This Post Helpful? -3
  • +
  • -

#7 azweed1990  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 6
  • Joined: 02-March 11

Posted 02 March 2011 - 09:16 PM

Thanks a lot for this mate you really helped me get started! could you take a look at
http://www.dreaminco...1&#entry1269281
and see if you could help me with that pls! i really really appriciate it mate!
cheers!

This post has been edited by azweed1990: 02 March 2011 - 09:23 PM

Was This Post Helpful? 0
  • +
  • -

#8 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 223
  • View blog
  • Posts: 773
  • Joined: 02-June 10

Posted 23 May 2011 - 04:50 AM

Done this before however the way you implemented this was rather nice (the patched up code :P )
Cool tutorial! Looked very helpful for beginners to game programming with Java and could excite more people to give it a go :)
Was This Post Helpful? 0
  • +
  • -

#9 Evann  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 07-July 11

Posted 07 July 2011 - 10:41 AM

Hi,
I'm using your code at the moment, but slightly adjusted so it works without the package since I'm not to confident about that, and have got it all to work except the hand.java. I've edited it a fair bit so it should just display the hand you receive, however I keep getting the error non-static variable cards cannot be referenced from a static context. The code is below:

public class Hand {

	private Card[] cards;
	private int[] value;

	
	Hand(Deck d)
	{
		cards = new Card[5];
		for (int x=0; x<5; x++)
		{
			cards[x] = d.drawFromDeck();
			
		}
	}
	public static void main (String args[]) {
		for (int y=0;y<5;y++) {
			System.out.println(cards[y]);
		}
	}
}


I've tried different methods and such, but generally couldn't get it to work, so I was wondering how the hand could be displayed.

Thanks,
Evan.
Was This Post Helpful? 0
  • +
  • -

#10 Candace_W  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 28-February 12

Posted 28 February 2012 - 09:13 PM

Hello. I enjoyed your tutorial, but when I tried using it, I got an error on line 20 "cards.add (new Card(a, B)." The error said "Constructor Card in class pokergame.Card cannot be applied to given types; required: short,short
found: int,int reason: actual argument "int" cannot be converted to short by method invocation conversion. Is that just my computer? Maybe I need to od it a different way? please help...
Was This Post Helpful? 0
  • +
  • -

#11 pascal7  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 12-May 12

Posted 15 May 2012 - 12:58 PM

Ok, so I ran the code, and all I get is the 52 cards..isn't it suppose to show a five card hand and pick the best poker-value given the 5 cards?

Also can you show how royal flush can be done?
Was This Post Helpful? 0
  • +
  • -

#12 Samagician  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 20-August 12

Posted 20 August 2012 - 10:15 PM

So I've followed this tutorial and I'm having a problem with the output of the Hand.display in the main. Flush is the only thing that is showing up and I've looked over all the code, so I'm not sure what needs to be changed
Was This Post Helpful? 0
  • +
  • -

#13 smohd  Icon User is offline

  • Critical Section
  • member icon


Reputation: 1820
  • View blog
  • Posts: 4,627
  • Joined: 14-March 10

Posted 20 August 2012 - 10:45 PM

Are you sure you put the display in the correct place? If you have followed the tutorial to the end, then I expect it to work fine.
If you cant sole your problem, please post the code which you have tried in Java forum and we will see what went wrong.
Was This Post Helpful? 0
  • +
  • -

#14 osis888  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 18-September 12

Posted 18 September 2012 - 06:57 AM

I made counter and Hand 1 beats Hand 2 more offten in long range, and thats happening every time :
PLayer 1 won 11582 times of 20000
PLayer 2 won 8418 times of 20000
Can you explain this ?
Was This Post Helpful? 0
  • +
  • -

#15 osis888  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 18-September 12

Posted 19 September 2012 - 03:44 AM

Oh, it's because comparing high cards , always wins first hand even if secound high card is higher...so there is bug too....
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2