In this post I will be showing a poker hand analyser. It will be able to be used in either 5 Card Poker or Texas Holdem. In this algorithm we are not checking all players hands, only one hand of 5 or 7 cards. It can be reused for each players hand. Let's start by first solving the problem, before we look at working on what the hand contains.
In poker there are ten possible hands. In order from best to worst they are;
- Royal Flush
- Straight Flush
- Four of a Kind
- Full House
- Flush
- Straight
- Three of a Kind
- Two Pair
- One Pair
- High card
There are a few things to look at before writing a poker hand analyser.
If you have a straight or a flush, you CAN NOT have a full house or four of a kind.
This is because having a straight or a flush takes five of the cards. In five card poker that's all your cards, and in texas hold'em you are left with only two cards to use. Its not enough to make anything else.
In Texas Hold'em, you CAN have a flush AND a straight WITHOUT it being a straight flush
Imagine you have a straight with 3 hearts and 2 clubs, then you have 2 more hearts no where near the straight. In this case you have both a straight and a flush. Since flush is better, the flush has to be used.
Ace must be used as both high AND low.
In a straight the ace has to be tested for low high and low straights.
In Texas Holdem, a players hand is 7 cards in total. Two in their hand and five on the table.
So let's get started. Below is a flow chart of the algorithm. Using this will enable us to test for the best hands first, and then moving through to the lowest hands without over checking. For example, if we don't have a flush there's no need to check for straight flush or royal flush.
Checking For A Flush
So let's say you were dealt this hand.
And out on the table we have.
The first thing we need to do is sort them into suits. Create four arrays named diamonds, hearts, clubs and spades. Next loop through each card and check the suit using a select case statement. In the case for each suit place the card in the relevant array.
Next all you need to do is check the length of each array. If its five or more then we have a flush. You can then return the flush array for further processing.
Checking For A Straight
Checking for a straight is a little more complex so we will go through this step by step. Let's say we have been dealt this hand.
And the table has.
First of all we need to sort the cards. This can be done with a bubble sort using the card value. In my example Ace has a card value of 14.
We already can see we have a straight using A, 2, 3, 4 & 5. Now before we loop through the cards we need a few variables for;
- Keeping count of the straight length (tempCount) preset to 1
- Keeping track of the start of the straight (startIndex) preset to -1
- Keeping track of the end of the straight (endIndex) preset to -1
- The lowest value card (lowestValue) preset to null
- Whether the ace is included or not. (aceIncluded) preset to false
So with those set up we can now loop through the cards backwards. Start with the highest value card and loop to the lowest. First thing you want to do is check if the card is an ace so we can use it as a low card too. In our example it is an ace, so we set aceInclude to true.
Next we check if the value of the card in the current loop is 1 greater in value than the card in the next loop.
This is true so we check if endIndex equals -1 and if so set endIndex to the current loops index. In this example 6. Add 1 to the tempCount which makes it 2 saying there are 2 cards in the straight, and the startIndex we set to this index - 1. In the example 5. And lastly set lowestValue to the value of the card in index - 1 (The King) which is 13.
Then we do the same again for the next card.
This one is false. So we first check if the card is the same value. King = 13 and 5 = 5 so they are not the same value (We'll see why we do this when we get to the two 4's. Now just check our count. If it already equals 5 we can break the loop. Otherwise we reset startIndex endIndex to -1 since we no longer have a straight potential. Set tempCount back to 1 and the lowestValue card to the value of the card in index - 1.
So let's continue a bit and do the next one.
Once again we are true so;
- endIndex = current index = 4
- startIndex = current index - 1 = 3
- tempCount increases by 1 = 2
- lowestValue = current index - 1's value = 4
Now the next step.
This time we are false, however both cards are of equal value. If we reset all the values we will loose our straight, and we can see we have one. However the computer can not see the cards ahead so in this case, we include the card in the straight but do not add to the tempCount.
- startIndex = currentIndex - 1 =3
To include it all we do is move the startIndex to that card. Because we haven't added 1 to the tempCount the computer still sees 2 cards to make up a straight but we have three cards to use. In the end we will only use one of the 4's
Checking the rest of the cards has already been explained so let's just rush through that.
Once again we are true so;
- endIndex does not equal -1 so we leave it alone
- startIndex = current index - 1 =1
- tempCount increases by 1 = 3
- lowestValue = current index - 1's value = 3
Now the last step in the cards
Once again we are true so;
- endIndex does not equal -1 so we leave it alone
- startIndex = current index - 1 =0
- tempCount increases by 1 = 4
- lowestValue = current index - 1's value = 2
So now we have looped through all the cards and counted our straight. To test if the straight is present all we need to do is check our tempCount. If the tempCount is equal to or greater than 5 than we have a straight. We can go ahead and use the startIndex and endIndex to create a new array containing the best hand for further procressing.
Now in our case we know we have a straight but our tempCount only equals 4. This is because the Ace is a part of our straight but it seen as a high card. So, if testing for 5 or more in the straight fails, test for 4 in the straight. If tempCount is equal to 4 we need to check the lowestValue. If the lowest value equals 2 in our straight of 4 then we know we have 2, 3, 4, 5. All we need is an ace to complete the straight. We already checked for an ace when we looped the cards the first time, so, if aceIncluded is equal to true,
AND tempCount is equal to 4
AND lowestValue is equal to 2 then we have a straight. Use startIndex and endIndex to get the first part of the straight and then get the card in the last index. Return these as your best hand for further processing.
Prepare For Four of a Kind, Three of a Kind, Full House and Pair Checks
It 's best to have the cards sorted by value before starting this.
Since check for these are all the same process, I decided to do it all in one sweep. We will do this similar to the flush with a few arrays. First start by making seven arrays. Since we have seven cards there is a chance to get seven different value cards. Lets call these temp1 through to temp7.
First we loop through each card checking it's value. Let's take our last hand as the example.
We can see we have a pair of 4's. Since we don't have set arrays for the card type we need to loop through each card check its value and then find either an array with the same value cards or an empty array. So let's start with the 2. First check the length of temp1. It's empty so it returns 0. We know the first array is empty so all the others will be too. Place the 2 in that array.
The next card is a three. First check temp1's length. This returns 1 so there's a card in there. Then check that cards value, which is 2. Its not the same as our card's value so we move to the next array. This one is empty so we can just put this card in.
Continue this for the next step.
Now this next card when checking the card values will match the card in temp3, so put it in the same array.
The rest of the cards won't match any arrays so after all the cards have been sorted will look like this.
Checking For Four of a Kind
To check for a four of a kind, simply loop through the arrays temp1 through to temp7 and see if any of them have a length of 4. If you find one, take that array and one card from the highest value array other then the array you are using, and return it as your best hand for further processing.
Checking For Three of a Kind AND Full House
To check for a three of a kind you can do the same process as with four of a kind, HOWEVER, in texas holdem, you have the potential for 2 sets of three. So, if you find a three of a kind you need to continue to see if you find another. If you do find another, the highest value set plus two cards from the lowest make up your best hand. If only one set of three is found it is taken as best hand along with two cards from the highest value other than the array you are using.
When you find only one three of a kind, you need to see if it's a full house. You need to then loop through and check for a pair. If you find a pair, check for a higher pair. Take the highest pair with the three of a kind and return it as best hand for further processing.
Checking For A Pair Or Two Pair
To check for a pair, loop through the arrays looking for pairs. There is a potential for three sets of pair so make sure you find the highest pairs. If you find 1 pair you have a pair, take that with the 3 highest value cards not including the pair and you have your best hand. If you find 2 pairs, take them and the highest value card not including your two pairs and you have your best hand. If you find 3 pairs, take the two best pairs along with the highest value card other than the pairs you are using and return it for your best hand.
Putting It All Together
So all of these things above can be placed in functions. You hand your 5 or 7 cards to the function and it either returns an empty array or an array of cards. Now all you need to do is may a anaylse hand function which follows the same process as the flow chart we made...
1. Is there a flush? To check what the function results are we check the length of the return array. If it is greater than 0 then we have a flush. Move to step 1 a. If its 0 move to step 2.
1a. Do we have a straight? Once again check the length of the returned array. If its greater than 0 then move to step 1. a i. Otherwise move to step 1. b)
1ai) Do we both the King and The Ace. To test for this loop through your returned cards and check for a value of 13 AND 14. If you find them both you have a
ROYAL FLUSH. If not you have a
STRAIGHT FLUSH.
1b. If we don't have a straight then we have a
FLUSH.
2. Do we have a straight? Once again check the length of the returned array. If its greater than 0 then we have a
STRAIGHT. If it is 0 then we move to step 3.
3. Sort out the cards into value arrays. Go to step 4
4. Do we have Four of a Kind? If yes,
FOUR OF A KIND, if not go to Step 5
5. Do we have Three of a Kind? If yes, go to step 5a. If not goto step 6.
5a. Do we have a full house? If yes,
FULL HOUSE if no
THREE OF A KIND
6. Do we have 1 pair? If yes Go to Step 6a. If not go to Step 7
6a. Do we have another pair? If yes,
TWO PAIR, if not
PAIR
7. Nothing else is possible so you have
HIGH CARD. Take the highest value cards from the hand as your best hand.
This algorithm can be streamlined heaps by doing things like breaking from loops if there ain't enough cards to complete what you are looking for. For example, if you are looking for a straight, and have 2 card already making up a straight but have only 2 cards left, there is no point checking them. You can not make a straight. Unless of course you have 5, 4 and an Ace. You may have 3 and 2 in the last one. But I'll leave it up to you to streamline.
I hope this helps with creating your poker app. If you need help writing it in a set language I am happy to write a post with that and link it to the bottom of this post. Just ask in the comments.