How to Code Poker Hands – Comparing Hands For A Straight

Continuing the series of comparing poker hands of the same rank, this article will show you how to write code to compare two straights to see which one wins.

In a previous article for poker hands, you saw how to check a hand to determine if a hand was a straight. A straight is a hand where the values of all five cards are in sequential order. Here’s an example of a straight:

From left to right, each card is one less than the last one.
Comparing Straight Hands

When both hands are a straight, it’s very easy to compare the hands. First, sort the cards in order of descending value, meaning from highest to lowest. Next, compare the first card (highest) card from each hand. The hand with the higher card is the hand with the higher-ranking flush. If both cards are equal, then both hands are of equal rank.

Have a look at this example, hand 2 has the higher-ranking flush, since a jack outranks an eight.

Hand 1
Hand 2

This works very well for card values two through ace. But what about dem pesky wild cards? 😼

Comparing Straight Hands With Wild Cards

Wildcards do complicate things a little, but it’s nothing we can’t handle. 😏

Note: You can’t compare straights with wild cards in them, so you have to substitute them for the correct values. Before, when all you were doing was determining if a hand is a straight or not, this was not necessary. However, before you can do a comparison, you need to have all the wilds gone.

When you have wildcards in a straight hand, you can do these three steps:

  1. Substitute card values for any values in between the highest and lowest card to fill out the straight. Use as many wilds as needed to fill out the gap between the highest and lowest card.
  2. If there are any wilds left over, and the highest card is not an ace, substitute one wild with a card value higher than the highest card.
    • Repeat step 2 until you have replaced a wild card with an ace, or you run out of wilds.
  3. If there are any wilds left over, and the lowest card is not a two, substitute one wild with a card value lower than the lowest card.
    • Repeat step 3 until you have replaced a wild card with a two, or you run out of wilds.

Some visual examples are always in order. 🙂

Example 1

Have a look at this hand:

Following step 1, you can substitute the two wilds with an eight and six, and you end up with:

Note: Remember, in a straight, as long as the hand contains at least two different suits, the suits don’t matter.

Example 2

Let’s try this hand:

Again, following step 1, we substitute wilds in between the highest and lowest values. Here, we’d use one wild and replace it with a nine, and we have:

We’ve one wild remaining, so we move on to step 2, and replace it with one higher than the highest card. So, you’d replace that wild with a queen, finally ending up with:

Example 3

Hey, lemme get another. Thanks, man. Good lookin’ out. 🤜🏾🤛🏾

Yep. (: If you’re holding these cards:

Step 1: There is no gap in between the queen and jack, so there’s nothing to do here.

Step 2: You can replace two cards higher then the queen, the king and ace. So you’d end up with this:

Step 3: With one wild left over, you replace it with one card lower than the lowest card, which currently is a jack. So, your final hand looks like:

Example 4

One final example. This one’s a bit of a smart-ass hand 😒

You can imagine some dude trying to put in all wilds to break the program. Yeah, well, you got his number, too.

Here, you have no existing card values from which to establish a highest or lowest card. So to make the best possible straight, you can simply replace it with a hand that looks like the previous example’s solution:

However, there is a more programmatic way of doing this other than simply a brute force hard-code, which I’ll show you how.

Because there are no card values, you can establish a “fake” highest and lowest value of “ace + 1”. Since the highest and lowest values are the same, step 1 is skipped. Since your highest value is higher than an ace (somehow, lol), step 2 is skipped.

That leaves step 3, so you start replacing wilds with values lower than the lowest value, which is also “ace + 1”. So the first wild would substitute “ace + 1 – 1” = ace. Then the next substitution is one lower than the lowest value, ace, which is ace – 1 = king.

Setup

Note: The first stages of the setup can be found on the introduction page to comparing poker hands, here.

There aren’t any other specific preparations we need before we begin.

Writing The Code For Comparing Two Straights

When both hands are straights, the GetWinningPlayerId function will eventually call the FindWinnerStraight function that compares them to determine which one wins.

First, if either hand contains any wild cards, you’ll need to substitute them using the three steps mentioned above. Once all wilds have been substituted in both hands, you can compare them.

Let’s start with the FindWinnerStraight function.

FindWinnerStraight
1
2
3
4
5
6
7
8
9
10
11
12
13
14
FindWinnerStraight = function(hand1, hand2) {
  SET workingHand1 = CardMatchUtils.SortCardsByDescendingValue(hand1);
  SET hand1Info to an empty object { }
  CardMatchUtils.AreCardsStraight(workingHand1, hand1Info)
  SET workingHand1 = WildsAssumeValues(workingHand1, hand1Info)
 
  SET sortedHand2 = CardMatchUtils.SortCardsByDescendingValue(hand2);
  SET hand2Info to an empty object { }
  CardMatchUtils.AreCardsStraight(workingHand2, hand2Info)
  SET workingHand2 = WildsAssumeValues(workingHand2, hand2Info)
 
  SET winningPlayerIndex = CardMatchUtils.CompareHands(workingHand1, workingHand2)
  RETURN winningPlayerIndex
}

In the psuedocode above, you may have noticed the AreCardsStraight function from before, but it now has a new parameter that wasn’t there before: “info”.

We’ll need to make some adjustments to the AreCardsStraight, because if wilds are in the hand, we want to know what values will be replacing these wilds (using the three steps above). We can store the values in the info.cardValues array, same one we’ve used in previous hand comparing functions.

So, our new ‘AreCardsStraight’ function looks like this:

AreCardsStraight
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
AreCardsStraight = FUNCTION(sortedHand, info) {
  SET numWilds to CardMatchUtils.CountCardsByValue(sortedHand, CardValues.wild)
  SET cardValues to an empty array []
 
  SET currentCardValue to 0
 
  (these will be used later, but we want to set them up here)
  SET highestCardValue to null
  SET lowestCardValue to null
 
  FOR EACH card in the sortedHand {
    IF this card (the current loop card) is a wild card
      IF (highestCardValue EQUALS null)
        (this is the first card being checked)
        SET highestCardValue to CardValues.ace + 1
      END
 
      EXIT FOR EACH LOOP
    END
 
    IF (this card is the first card being checked)
      SET currentCardValue to the value of this card (card.value)
      SET highestCardValue to currentCardValue
      CONTINUE FOR LOOP again with next card (in other words, "continue" if you're familiar with for-loops)
    END
 
    SET valueDifference to currentCardValue - card.value
    SET currentCardValue to card.value
 
    IF valueDifference EQUALS 1
      CONTINUE FOR LOOP again with next card (the condition for the straight is met so far)
    END
 
    IF valueDifference EQUALS 0
      RETURN FALSE (this card has the same value as the previous card's stored in currentCardValue, the card from the previous loop iteration - this hand is not a straight)
    END
 
    SET lowestCardValue to currentCardValue
 
    (check if there are enough wilds remaining to cover the difference in card values)
    SET numWildsToUse to valueDifference - 1
    IF numWilds GREATER THAN 0 AND numWilds IS GREATER THAN OR EQUALS numWildsToUse
      (there are enough wilds, deduct that from the number of wilds available, and straight is still satisfied
      SET numWilds to numWilds - numWildsToUse
 
      (fill in the actial card values that will be replacing the wilds)
      SET wildIndex to 0
 
      WHILE wildIndex IS LESS THAN numWildsToUse
        (repeat these steps as long as the WHILE condition is true)
        SET substitutedCardValue to cardValue + wildIndex + 1
        ADD substitutedCardValue into array cardValues
        SET wildIndex to wildIndex + 1
      END
    ELSE
      RETURN FALSE (there are not enough wilds to cover the range in value between the two cards - this hand is not a straight)
    END
  END
 
  (straight is satisfied through all cards - success!)
 
  (if there are any wilds remaining, try to assume values higher than the highest non-wild)
  IF highestCardValue EQUALS null
    SET highestCardValue to CardValues.ace
  END
 
  SET numWildsToUse to numWilds
  WHILE (numWildsToUse IS GREATER THAN 0) {
    SET cardValue to highestCardValue + (numWilds - numWildsToUse) + 1
    IF (cardValue IS LESS THAN OR EQUALS CardValues.ace)
      ADD cardValue into array cardValues
      SET numWildsToUse to numWildsToUse - 1
    ELSE
      EXIT WHILE LOOP
    END
  END
 
  (if there are any wilds remaining after assuming the higher values, try to assume values lower than the lowest non-wild)
  IF (lowestCardValue EQUALS null
    SET lowestCardValue to highestCardValue
  END
 
  SET offset to 0
  WHILE offset IS LESS THAN numWildsToUse
    SET cardValue to lowestCardValue - offset - 1
    ADD cardValue into array cardValues
    SET offset to offset + 1
  END
 
  IF info IS SPECIFIED
    SET info.numWilds to numWilds
    SET into.cardValues to array cardValues
  END
 
  RETURN TRUE
}

Wow! 😮 This is a little more than our original AreCardsStraight function! But it now handles all three steps of replacing wilds with the correct card values. If you got nothing else from this, know that the AreCardsStraight can now return to you those cardValues. 😉

Note that this function does not replace the cards in the hand itself. We’ll be doing that next; the main function of AreCardsStraight is still to determine if a hand is straight, and you can specify an optional info only if you need to know how many wilds are in the hand, and which card values would replace them to make a wild-less hand.

Replacing The Wild Cards With Card Values

Going back to the FindWinnerStraight, you maye have noticed a new function you’ve never seen before, called WildsAssumeValues. It accepts two parameters, a hand (an array or Card objects), and an info object. What this function will do is return a new hand, with all the wilds replaced with the values specified in the info.cardValues array.

Let’s have a look.

WildsAssumeValues
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WildsAssumeValues = function(hand, info) {
  SET index to 0
  WHILE index IS LESS THAN number of cards in the hand (for example, "hand.length")
    SET card = hand[index] (get the nth card in hand)
 
    IF the card is a wild (card.value EQUALS CardValues.wild)
      SET the card value to the last value in the info.cardValues array
      REMOVE the last card value from the info.cardValues array (info.cardValues.pop())
    END
 
    SET index = index + 1
  END
 
  SET sortedHand to CardMatchUtils.SortCardsByDescendingValue(hand)
  RETURN sortedHand
}

All the WildsAssumeValues does is go through the hand, replacing any wilds it finds with a value from the info.cardValues array. Then, it removes that value from the array to make sure it’s not used again. Finally, it creates a new hand and sorts the cards by card value in descending order, and returns that new hand. This new hand is what we’ll use to compare straights with.

Back in the FindWinnerStraight function, at this point, you’ll now have two hands with any wilds replaced with actual card values, and you can finally compare both hands using the CardMatchUtils.CompareHands function.

Remember, CardMatchUtils.CompareHands will return 1 if the first hand wins, -1 if the second hand winds, or 0 if both hands are tied.

That’s it for comparing two straight hands! Now, if you like, you can play with creating your own hands using the controls below. Enjoy! 😎

Compare Your Own Hands


Player 1

Result: HIGH CARD

Player 2

Result: HIGH CARD

Player 3

Result: HIGH CARD

Who Won: Player 3

If you have any questions about anything in this article, please let me know at cartrell@gameplaycoder.com.

Thanks, take care, and until next time,

– C. out.

How to Code Poker Hands – Comparing Hands For A Three Of A Kind

When you have two poker hands and both are a three of a kind, this article will show you how to compare those hands and determine which one wins.

In a previous article for poker hands, you saw how to compare a hand to determine if a hand was three of a kind. A three of a kind is a hand three of the cards are the same value, and the remaining two cards are of different, non-pair values. Here’s an example of a three of a kind:

There are three 7s, and the remaining two cards, the eight and ten, are different values from the sevens and each other, so they don’t form a pair.

When determining the winner between two hands that are both three of a kind, the process is very similar to the pair’s, except we’re dealing with a trio instead fo a pair:

  1. Compare the values of the trios.
  2. If those values are equal, compare the values of other two cards (the “kickers“), starting with the highest one.
  3. Continue comparing kickers until a kicker from one hand is higher than the other’s.
  4. If no kicker breaks the tie, and all cards have been compared, then both hands are equal.

Some examples should help with explaining the concepts.

Consider these two hands:

Hand 1
Hand 2

Note: Just like with pairs being first sorted by the pairs,, the cards are sorted first the trio, then by the kickers in descending order of value. The hands above are already sorted this way.

First, compare the value of the trios. Hand 1 has trio of 8s, and hand 2 has a trio of 9s. So hand 2 wins this contest.

Let’s try another. Let’s say the values of the trios of both hands are the same as shown here:

Hand 1
Hand 2

Both hands have the same trio value of three. So you compare the kickers.

The values of first the kicker of each hand is a seven, so we’re tied. Let’s compare the second and final kicker.
You can see that 6 > 4, so the first hand has the higher three of a kind.

And we can’t forget about our crazy wild cat wild cards! 😼 They always seem to throw a 🐵 🔧 into our plans. But we’re going to consider them as well.

Have a look:

Hand 1
Hand 2

In hand 1, we have a trio value of kings, and the a wild card is one of the kickers. Hand 2 also has a trio value of kings (the wild card substituting as a king). Since both hands have the same trio value (king), let’s compare the kickers.

Remember that a wild card can assume any value, and in our case, we want the wild card to assume the highest possible value (while still satisfying the hand and form the highest possible hand: see the note below). In the case of hand 1, the wild card assumes the value of a ace. If you compare that to hand 2’s first kicker, an ace beats a 10. So hand 1 is the winner here.

Note: In hand 1 above, you could’ve also formed the three of a kind by substituting the wild for a king like this:

However, if you use as many non-wild cards as possible to form your three of a kind, when using wild cards won’t increase the trio value, you can save any remaining wilds for as kickers. It will always be substituted as an ace, thus giving you the highest possible hand. When comparing hands, the code introduced in this article will help with that.

Setup

Note: The first stages of the setup can be found on the introduction page to comparing poker hands, here.

There aren’t any other specific preparations we need before we begin.

Writing The Code For Comparing Threes Of Kinds

When two hands are both a pair of jacks or better, the GetWinningHand function will eventually call a function that compares two hands of said poker hand.

In this case, GetWinningHand function will eventually call FindWinnerJacksOrBetter to compare the hands. Just like FindWinnerHighCard from the last article, FindWinnerJacksOrBetter accepts two parameters, the hand for both players, and it’ll return the ID of the player who has the winning hand. If both hands are equal, it’ll return 0 (which we’ll use to mean a draw). The pseudocode below starts by comparing the values of the pairs first, then comparing the kickers if necessary.

FindWinnerThreeKind
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FindWinnerThreeKind = function(hand1, hand2) {
  sortedHand1 = CardMatchUtils.SortCardsByDescendingValue(hand1);
  SET hand1Info to an empty object { }
  CardMatchUtils.DoCardsHaveSameValue(hand1, 3, hand1Info);
   
  sortedHand2 = CardMatchUtils.SortCardsByDescendingValue(hand2);
  SET hand2Info to an empty object { }
  CardMatchUtils.DoCardsHaveSameValue(hand2, 3, hand2Info);
   
  SET winningIndex = CompareTrios(hand1, hand1Info, hand2, hand2Info);
  IF (winningIndex NOT EQUAL TO -1)
    RETURN winningIndex (one hand's trio outranks the other hand's, and no further checking is necessary)
  END
   
  (both hands have the same ranking trio, now compare the kickers of both hands)
  SET winningIndex = CompareKickers(hand1, hand1Info, hand2, hand2Info);
  RETURN winningIndex;
}
Comparing the Trios

First the code above sets the hands up for comparing their trios. It then sort the cards in descending card value. Next, it uses the DoCardsHaveSameValue function to get the three cards in the hand that make the trio, as well as determine the card value of the trio.

CompareTrios
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CompareTrios = function(hand1, hand1Info, hand2, hand2Info) {
  SET hand1WorkingTrioValue = hand1Info.cardValues[0]
  IF (CardMatchUtils.CountCardsByValue(hand1, WILD_VALUE) GREATER OR EQUALS 3)
    hand1WorkingPairValue = ACE_VALUE
 
  SET hand2WorkingTrioValue = hand2Info.cardValues[0]
  IF (CardMatchUtils.CountCardsByValue(hand2, WILD_VALUE) GREATER OR EQUALS 3)
    hand2WorkingTrioValue = ACE_VALUE
 
  IF (hand1WorkingTrioValue > hand2WorkingTrioValue)
    RETURN 0 (hand 1 has the higher ranking trio)
  ELSE IF (hand1WorkingTrioValue < hand2WorkingTrioValue)
    RETURN 1 (hand 2 has the higher ranking trio)
  END
 
  RETURN -1 (both hands' trios have the same value)
}

This function is very similar to the ComparePairs function in our recent article for comparing pairs of jacks or better, except instead of dealing with two cards, we’re dealing with three. If you’d like details on the workings of that function, please check here.

Comparing the Kickers

If the trios of both hands have the same rank, then you’ll need to compare the other two cards, the kickers.

Like you did when comparing the kickers with previous poker hands, when comparing the kickers, you first remove the trios from both hands so you’re left with the remaining kickers. You can use the CardMatchUtils.BuildHandExcludingValues function to remove the trio.

You can use this psuedocode to get the kickers in the hand:

GetKickers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
GetKickers = function(hand, info) {
  (get the value of the cards that form the trio)
  SET trioCardValue = info.cardValues[0]
 
  (count the number of cards in the hand that match the trio card value)
  SET numTrioValueCards = CardMatchUtils.CountCardsByValue(hand, trioCardValue)
 
  (if there are at least as many trio value cards as there are non-kicker cards, specify the trio card value to the values of cards to exclude)
  SET numNonKickerCards = 3
  IF numTrioValueCards >= numNonKickerCards
    SET valuesToExclude = trioCardValue
 
  ELSE {
    (otherwise, if there are at least as many wild cards as there are non-kicker cards, add the wild card value to the values of cards to exclude)
    SET numWildCards = CardMatchUtils.CountCardsByValue(hand, CardValues.WILD)
    IF numWildCards >= numNonKickerCards
      SET valuesToExclude = CardValues.WILD
    ELSE
      (finally, specify BOTH, the trio card value and the wild card value as the values of cards to exclude)
      SET valuesToExclude = [ CardValues.WILD, trioCardValue ]
    END
  }
 
  (create the temporary kickers hand by excluding the specified values and returning the rest)
  SET handOfKickers = CardMatchUtils.BuildHandExcludingValues(hand, valuesToExclude, numNonKickerCards)
 
  (finally, sort the kickers hand in descending order, with wilds as the highest value)
  handOfKickers = CardMatchUtils.SortCardsByDescendingValueHighWilds(handOfKickers)
 
  RETURN handOfKickers
}

In the GetKickers above, the info object is the same one used in FindWinnerThreeKind. It was the hand1Info or hand2Info object, depending on which hand you’re getting the kickers from.

There are three situations in GetKickers that determine which values of cards to exclude as kickers.

The first is the simplest. It’s the trio card value used to form the three of a kind; they obviously can’t be the kickers. That means they will be excluded, leaving the remaining two cards as the kickers.

The second situation is that if the hand contains at least three wilds cards. These cards can assume the highest non-wild value, which is an ace. So three wilds would form a three of a kind, using an ace as the trio card value. So the wild card value would be excluded from the hand of kickers.

Finally, the hand doesn’t have three cards with the same value, but it does contain two wild cards. Those wilds will still assume the value of the highest non-wild card, forming the three of a kind. The trio card value is whatever value those wilds card assumed. In this situation, you want to exclude both values of both, the wild card, and the trio card value.

Note: When excluding cards, you’re always excluding exactly three cards (the number of non-kicker cards).

Comparing The Kickers

I hope you are still with me at this point. If you’re reading this far, I suppose it goes without asking 😉

When comparing which three-of-a-kind hand winds, if the trio values of both hands are the same, then you need to compare one or both of the kicker cards from both hands to determine the winner.

CompareKickers
1
2
3
4
5
6
CompareKickers = function(hand1, hand1Info, hand2, hand2Info) {
  SET hand1Kickers = GetKickers(hand1, hand1Info)
  SET hand2Kickers = GetKickers(hand2, hand2Info)
  SET winningPlayerIndex = CardMatchUtils.CompareHands(hand1Kickers, hand2Kickers)
  RETURN winningPlayerIndex
}

The CardMatchUtils.CompareHands function is the same one we used here.

The CompareKickers will return 0 if hand1 has the better kickers (and thus the better three-of-a-kind-hand), 1 if hand2 has the better kickers, or -1 if both hands are the same rank.

That’s it for this article. As we write more solutions, we can often re-use code from previous ones to help simply and speed up the process.

Compare Your Own Hands

You can use the controls below to build your own hands and compare threes of kinds. Have some fun playing around with it, and if you find an issue, please let me know!


Player 1

Result:

Player 2

Result:

Player 3

Result:

Who Won:

If you have any questions about the content in this article, go ahead and let me know at cartrell@gameplaycoder.com.

Thanks and take care,

– C. out.

How to Code Poker Hands – Comparing Hands For A Two Pair

When you have two poker hands and both are a two pair, this article will show you how to compare them and determine which one ranks higher.

In a previous article for poker hands, you saw how to compare a hand to determine if a hand was a two pair. The pairs in the hand are made of two different values, and a fifth card with a different value from either of the pairs. Here’s an example of a two pair:

The is a “two pair, queens and fives”, and the kicker card is a jack.

When determining the winner between two hands that are both a two pair, the process is very similar to the pair’s, except we’re dealing with two pairs in each hand instead of one:

  1. Compare the values of each hand’s higher pair.
  2. If those values are equal, compare the values of each hand’s lower pair.
  3. If those are equal, compare the values of the final card (the “kickers” ) in each hand.
  4. Finally, if the kicker does not breaks the tie, then both hands are equal.

Let’s have a look at an example.

Hand 1
Hand 2

In hand 1, the value of its higher pair is five, and hand 2’s is six. So, hand 2 is the winner.

Now, consider these hands:

Hand 1
Hand 2

The higher pair in hand 1 has a value of five, and so does hand 2. So move onto the lower pair.

The value of hand 1’s lower pair is four, while hand 2’s is three. This time, hand 1 is the winner.

And if the values of the pairs in both hands are equal, then you’d go on to compare the final kicker card of each hand.

Wild Cards

But what about wild cards!? 😮

Yeah, guess we shoulda seen that one comin’. 😉

Remember that a wild card can assume the value of any card. If your hand has a pair of wilds in it, then both wilds can assume the highest value, ace. Have a look at this:

The suits of the aces don’t matter; wilds only care about card values in the case of a two pair.

If the hand only contained a pair one wild, and two other cards of different values, then the wild would assume other card with the higher value. So, if the hand was this:

The wild would assume the value of jack, because that’s the highest non-paired card. So the hand acts like:

This creates a challenge for us in a few ways, and we’ll need to make some changes to how two pairs are even matched in the first place.

Setup

Note: The first stages of the setup can be found on the introduction page to comparing poker hands, here.

There aren’t any other specific preparations we need before we begin.

Writing The Code For Comparing Two Pairs

When two hands are both a two pair, the GetWinningHandfunction will eventually call a function that compares both of these types of hands.

But before we do that, we’ll need a way to get the values of both pairs in a hand when we compare the hand to another two-pair hand.

Have a look at this hand:

If you go back to examine the psuedocode of the TwoPair function, you’ll see that it calls CardsHaveSameValue(sortedHand, 2, wildsInfo) twice. That’s because it’s checking to see if 2 cards have the same value twice.

There are two caveats to this function.

One is that it could find two pairs, where both pairs have the same value, something like:

While technically, this hand contains two pairs of cards, it’s not a two pair, because the pairs are the same value. Also, if you’ve implemented a system, where you’re matching hands, starting with the highest ranking hand and working down, this hand would always be matched as a four of a kind before ever being evaluated as a two pair.

The second caveat is that the info.cardValues array inside the parameter of CardsHaveSameValue does not report the correct value if our hand has only one pair and a wild. After calling CardsHaveSameValue twice, it would report the cardValues of the two cards found would be CardValues.JACK and CardValues.TWO! It should’ve reported CardValues.NINE instead! When you’re simply matching for a two pair hand, it doesn’t matter which card values get reported, since they aren’t used anyway. But if you’re comparing two hands of a two pair, that’s a whole ‘nother story. The correct values of the pairs are important.

We won’t make any adjustments to CardsHaveSameValue since it works well for out matching situations. We don’t want to break anything. So, getting the correct pairs will require some custom code for comparing two pairs.

Let’s begin, shall we? 😏

Our main function, GetWinningHand will eventually call FindWinnerTwoPair to compare the hands. Just like the previous FindWinnerHighCard and FindWinnerJacksOrBetter functions from previous articles, FindWinnerTwoPair accepts two parameters, the hand for both players, and it’ll return the ID of the player who has the winning hand. If both hands are equal, it’ll return 0 (which we’ll use to mean a draw). The pseudocode below starts by comparing the values of the pairs first, then comparing the kickers if necessary.

FindWinnerTwoPair
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FindWinnerTwoPair = function(hand1, hand2) {
  sortedHand1 = CardMatchUtils.SortCardsByDescendingValue(hand1);
  SET hand1Info to an empty object { }
  SetInfoAndCheckForTwoPair(hand1, hand1Info);
 
  sortedHand2 = CardMatchUtils.SortCardsByDescendingValue(hand2);
  SET hand2Info to an empty object { }
  SetInfoAndCheckForTwoPair(hand2, hand2Info);
 
  SET winningIndex = ComparePairs(hand1, hand1Info, hand2, hand2Info);
  IF (winningIndex NOT EQUAL TO -1)
    RETURN winningIndex (one hand's pairs outranks the other hand's, and no further checking is necessary)
  END
 
  (both hands have the same ranking pairs, now compare the kickers of both hands)
  SET winningIndex = CompareKickers(hand1, hand1Info, hand2, hand2Info);
  RETURN winningIndex;
}

The FindWinnerTwoPair function uses a few new functions, SetInfoAndCheckForTwoPair and ComparePairs, and we’ll get into those below.

Checking For A Two Pair And Getting The Pair Values

This function will check for a two pair with two unique values of pairs, and it will update the info parameter sent to it.

SetInfoAndCheckForTwoPair
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
SetInfoAndCheckForTwoPair = function(hand, info) {
  IF info not is specified
    SET info to an empty object { }
  END
 
  IF info does not contain the property cardValues
    SET info.cardValues to an empty array [ ]
  END
 
  SET valueCounts to CountCardValues(hand) (count the number of times each card value appears in the hand)
  FOR EACH valueCount found in valueCounts
    IF the number of times that value was found EQUALS two (valueCount.count == 2)
      add that card value to the end of the info.cardValues array
    END
  END
 
  IF the number of values in the info.cardValues array EQUALS two (info.cardValues.length == 2)
    (we have two pairs with unique values, so the two pair is satisfied, we can exit here with success)
    sort the values in info.cardValues in descending order (highest to lowest)
    RETURN TRUE
  END
 
  IF the number of values in the info.cardValues array EQUALS one (info.cardValues.length == 1)
    (only found one pair, check if the other pair could be formed using wilds, if any exist)
 
    (exclude the two cards that form the pair from the hand using the frst [and only] card value in the info.cardValues array)
    SET handMinusPair = CardMatchUtils.BuildHandExcludingValues(hand, 2, info.cardValues[0])
 
    IF CardMatchUtils.DoCardsHaveSameValue(handMinusPair, 2, info) == TRUE
      (There was a wild in the remaining three cards that formed a pair with the highest value. The DoCardsHaveSameValue will add that card's value
      onto the end of the info.cardValues array.)
 
      sort the values in info.cardValues in descending order (highest to lowest))
      RETURN TRUE
    END
  END
 
  (this hand is not a two pair, exit with failure)
  RETURN FALSE
}
Counting Card Values

This function counts how many times the values of each card in the hand appears. This is useful for counting pairs, and generic enough to put into CardMatchUtils.

CountCardValues
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CardMatchUtils.CountCardValues = function(hand) {
  SET countValues to an empty array [ ]
 
  FOR EACH card in the hand
    FOR EACH countValueUnit in countValues
      IF countValueUnit.value EQUALS card.value
        ADD 1 onto countValueUnit.count
      END
    END
 
    IF none of the current count value units in countValues have a value that equals the card's value
      (add a new count value unit onto the countValues array with these values)
      countValues.push({
        value: card.value
        count: 1
      })
    END
  END
 
  RETURN countValues
}

Quite a lot here, right. Let’s have a closer look, shall we? 🙃

First, have a look at SetInfoAndCheckForTwoPair. This function accepts two parameters:

  1. The hand of cards, already sorted in descending order, wilds last.
  2. An optional info parameter.

When the function first runs, if no info parameter is specified (which would be the case if you’re only matching for a two pair and not comparing it), then one is created for use of this function. Otherwise, the info object specified is used, and modified by this function (for later use). We also want to create a new cardValues array property inside the info object and set it to an empty array [ ].

After that, the function counts the number of times each card value appears in the hand. This introduces a new function that you can place in your CardMatchUtils called CountCardValues.

So if you looked at our previous hand:

When we count the values in it, the CountCardValues would return this array:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[
  {
    value: 11 (CardValue.jack),
    count: 2
  },
 
  {
    value: 9 (CardValue.nine),
    count: 1
  },
 
  {
    value: 2 (CardValue.two),
    count: 1
  },
 
  {
    value: 100 (CardValue.wild),
    count: 1
  }
]
Resolving The Pairs

Back to the SetInfoAndCheckForTwoPair function: for those elements in this array that have a count property of 2, add them those values to the info.cardValues array. In this case, only the pair of jacks was found, so your info.cardValues looks like [ 11 ].

Next, if after counting card values, our info.cardValues has exactly two elements in it, this means it found two pairs of unique values. So, we’ve satisfied the condition of a two pair, and we can exit with success.

However, as in our example, we only found one pair. So we need to check the remaining three cards.

At this point, CardMatchUtils.DoCardsHaveSameValue would not have any adverse side effects if we used it on the remaining three cards, because if a wild was one of them, it would assume the highest value between the other two cards.

It would be nice if we could temporarily remove the first pair so we could easily compare the remaining three. Fortunately, we already have a CardMatchUtils.BuildHandExcludingValues function that can do just that! 😎

So there is this line in the SetInfoAndCheckForTwoPair function:
SET handMinusPair = CardMatchUtils.BuildHandExcludingValues(hand, 2, info.cardValues[0])
It builds us a new temporary hand without the jacks in it (or whatever the value of the first pair was).

In SetInfoAndCheckForTwoPair, we can then go on to call:
CardMatchUtils.DoCardsHaveSameValue(handMinusPair, 2, info)
And if it returns TRUE, then:

  1. A pair formed using a wild was possible
  2. The info.cardValue array will be updated (by DoCardsHaveSameValue) which will contain the value that the wild assumed. In this case, a nine.

Finally, in SetInfoAndCheckForTwoPair just before, and if, it finds success, it sorts the values in the info.cardValues array in descending order (highest to lowest). It does this because when comparing the pairs of both hands, this makes comparisons easier, because we’ll be comparing the higher-ranking pair of one hand to the other hand’s higher-ranking pair. Then, if necessary, the lower-ranking pairs.

So when SetInfoAndCheckForTwoPair completes and it returns TRUE, not only will yo have a valid two-pair hand, but then you’ll also know the values of both pairs.

Comparing The Pairs

The next major function in FindWinnerTwoPair is ComparePairs. This will compare the values of the pairs of both hands and return 0 if the first hand wins, 1 if the second hand wins, or -1 if both hands are equal.

ComparePairs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
ComparePairs = function(hand1, hand1Info, hand2, hand2Info) {
  (compare the higher-ranking pairs of each hand first)
  SET hand1WorkingPairValue = hand1Info.cardValues[0]
  IF hand1WorkingPairValue EQUALS WILD_VALUE
    hand1WorkingPairValue = ACE_VALUE
 
  SET hand2WorkingPairValue = hand2Info.cardValues[0]
  IF hand2WorkingPairValue EQUALS WILD_VALUE
    hand2WorkingPairValue = ACE_VALUE
 
  IF (hand1WorkingPairValue > hand2WorkingPairValue)
    RETURN 0 (hand 1's higher-ranking pair wins)
  ELSE IF (hand1WorkingPairValue < hand2WorkingPairValue)
    RETURN 1 (hand 2's higher-ranking pair wins)
  END
 
  (compare the lower-ranking pairs of each hand first)
  SET hand1WorkingPairValue = hand1Info.cardValues[1]
  IF hand1WorkingPairValue EQUALS WILD_VALUE
    hand1WorkingPairValue = ACE_VALUE
 
  SET hand2WorkingPairValue = hand2Info.cardValues[1]
  IF hand2WorkingPairValue EQUALS WILD_VALUE
    hand2WorkingPairValue = ACE_VALUE
 
  IF (hand1WorkingPairValue > hand2WorkingPairValue)
    RETURN 0 (hand 1's lower-ranking pair wins)
  ELSE IF (hand1WorkingPairValue < hand2WorkingPairValue)
    RETURN 1 (hand 2's lower-ranking pair wins)
  END
 
  RETURN -1 (both pairs in both hands are equally ranked)
}

The ComparePairs is similar to past ones we’ve written, except the main difference her is, we’re comparing two pairs instead of one. Also, this is why sorting the values in the info.cardValues array in descending order (highest to lowest) is so important.

As you can see, when comparing the higher-ranking pairs of both hands we use cardValues[0] from both hands’ info object. Then if they are equal, we compare the lower-ranking pairs using cardValues[1].

We also do the usual replacing of wild values with aces if the value of a pair is a wild.

Comparing The Kickers

It’s down to the final stretch. Both hands are neck and neck so far, and it’s come down to that final x-factor card for a possible tie-breaker.

CompareKickers
1
2
3
4
5
6
CompareKickers = function(hand1, hand1Info, hand2, hand2Info) {
  SET hand1Kickers = GetKickers(hand1, hand1Info)
  SET hand2Kickers = GetKickers(hand2, hand2Info)
  SET winningPlayerIndex = CardMatchUtils.CompareHands(hand1Kickers, hand2Kickers)
  RETURN winningPlayerIndex
}

This function gets the kicker card. To do this, you exclude from the hand, all other cards that make up both pairs. This happens inside the GetKickers function.

GetKickers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
GetKickers = function(hand, info) {
  SET valuesToExclude to an empty array [ ]
 
  (set the higher-ranking pair of cards to be excluded)
  SET pairValue to info.cardValues[0]
  IF the number of cards in the hand with the value of pairValue EQUALS 2
    add pairValue to the valuesToExclude array
  ELSE IF the number of wild cards in the hand EQUALS 2
    add CardValues.wild to the valuesToExclude array
  ELSE
    add both, pairValue and CardValues.wild to the valuesToExclude array
  END
 
  (set the lower-ranking pair of cards to be excluded)
  SET pairValue to info.cardValues[1]
  IF the number of cards in the hand with the value of pairValue EQUALS 2
    add pairValue to the valuesToExclude array
  ELSE IF the number of wild cards in the hand EQUALS 2
    add CardValues.wild to the valuesToExclude array
  ELSE
    add both, pairValue and CardValues.wild to the valuesToExclude array
  END
 
  SET kickers to CardMatchUtils.BuildHandExcludingValues(hand, valuesToExclude, 4)
  RETURN kickers
}

This function will exclude all cards found in pairs, leaving only one card remaining. Even though CardMatchUtils.BuildHandExcludingValues returns a hand (an array of Card objects), the array will always contain just one Card in it.

Now that you have the kickers in both hands, you can compare those cards. Since it’s only one card for each, you could just write a straight up comparison, and return the appropriate index depending on the result.

However, I think it’s still better to write:
SET winningPlayerIndex = CardMatchUtils.CompareHands(hand1Kickers, hand2Kickers)
because we already have that comparison code written, and it’ll already return the appropriate index for us, leaving the code here cleaner. 😉

Conclusion

Whew! This one was pretty meticulous just to compare two hands of two-pairs to see which one won! But I think you’ll be pleased with the result once it’s all working.

Compare Your Own Hands

You can use the controls below to build your own hands and compare hands of two pairs. Have some fun playing around with it, and if you find an issue, please let me know!


Player 1

Result:

Player 2

Result:

Player 3

Result:

Who Won:

If you have any questions about anything in this article, please let me know at cartrell@gameplaycoder.com.

Thanks and take care,

– C. out.

How to Code Poker Hands – Comparing Hands For A Jacks Or Better Pair

When you have two poker hands, both are a Jacks or Better pair, this article will show you how to compare those hands and determine which hand wins.

We previously went over how to determine if a hand is a jacks or better pair.

A jacks or higher pair is a poker hand that where exactly two of its cards have the same value, which is a jack or higher.

When determining the winner between two hands that are jacks-or-better pairs, follow this process.

  1. Compare the values of the pairs.
  2. If those values are equal, compare the values of other three cards (the “kickers“), starting with the highest one.
  3. Continue comparing kickers until a kicker from one hand is higher than the other’s.
  4. If no kicker breaks the tie, and all cards have been compared, then both hands are equal.

Let’s look at some examples.

Say we have these two hands:

Hand 1
Hand 2

It’s best to sort the cards in descending value order (from highest to lowest), first by the pairs, then by the kickers. So we rearrange the cards in both hands to look like:

Hand 1
Hand 2

Note: The suits don’t matter, only the order of the card values.

You can see that hand 1 has a pair of kings, while hand 2 has a pair of jacks. Kings easily beats jacks, so hand 1 wins.

But what both hands hand pairs of the same value? Let’s try another.

Hand 1
Hand 2

After sorting, we get:

Hand 1
Hand 2

Both hands have a pair of queens, so we’ll need to look at the three kicker cards of each hand.

The first one is a 9 in both hands, so you move onto the next card. The second is a 7 in both hands, still no tie breaker. So we move on to the final card. Hand 1 has a 2, while hand 2 has a 3. So hand 2 has the higher-ranking pair and wins this battle.

Setup

Note: The first stages of the setup can be found on the introduction page to comparing poker hands, here ( https://gameplaycoder.com/how-to-code-poker-hands-comparing-hands/#setup ).

There aren’t any other specific preparations we need before we begin.

Writing The Code For Comparing Pairs of Jacks Or Better

When two hands are both a pair of jacks or better, the GetWinningHand function will eventually call a function that compares two jacks or better pairs.

In this case, GetWinningHand function will eventually call FindWinnerJacksOrBetter to compare the hands. Just like FindWinnerHighCard from the last article, FindWinnerJacksOrBetter accepts two parameters, the hand for both players, and it’ll return the ID of the player who has the winning hand. If both hands are equal, it’ll return -1 (which we’ll use to mean a draw). The pseudocode below starts by comparing the values of the pairs first, then comparing the kickers if necessary.

FindWinnerJacksOrBetter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FindWinnerJacksOrBetter = function(hand1, hand2) {
  sortedHand1 = CardMatchUtils.SortCardsByDescendingValue(hand1);
  SET hand1Info to an empty object { }
  CardMatchUtils.DoCardsHaveSameValue(hand1, 2, hand1Info);
 
  sortedHand2 = CardMatchUtils.SortCardsByDescendingValue(hand2);
  SET hand2Info to an empty object { }
  CardMatchUtils.DoCardsHaveSameValue(hand2, 2, hand2Info);
 
  SET winningIndex = ComparePairs(hand1, hand1Info, hand2, hand2Info);
  IF (winningIndex NOT EQUAL TO -1)
    RETURN winningIndex (one hand's pair outranks the other hand's, and no further checking is necessary)
  END
 
  (both hands have the same ranking pair, now compare the kickers of both hands)
  SET winningIndex = CompareKickers(hand1, hand1Info, hand2, hand2Info);
  RETURN winningIndex;
}
Comparing the Pairs

The first half of this function sets up the hands for comparing their pairs. It sorts the cards in descending card value. Next, it uses the DoCardsHaveSameValue function to get the two cards in the hand that make up the pair.

But there is a problem here. We’d like to compare the values of the pairs here, and you may recall that DoCardsHaveSameValue only tells us if there are a certain number of cards in the hand that have the same value (in this case 2). It doesn’t tell us what that value is.

So, you’ll need to make some adjustments to your DoCardsHaveSameValue function. We can add this data to our custom wildsInfo parameter.

Open your CardMatchUtils source file, and find the DoCardsHaveSameValue function. Inside that function, at the beginning of it, add a new variable named cardValues and assign it an empty array [].

Next, if an info object was sent as a parameter to the DoCardsHaveSameValue function, assign its cardValues property to your cardValues variable:

1
2
3
if ("cardValues" in info) {
  cardValues = info.cardValues;
}

Next, at every point within DoCardsHaveSameValue, when the function is about to return true (this is also when it updates its info parameter if one was specified just before returning), add the following code:

  1. Add the current base card value to your cardValues array:
    cardValues.push(u_baseCardValue);
  2. Add the cardValues array as a property to your info object:
    info.cardValues = cardValues;

What this code does is tell us what the value of the card was that was found the requested number of times.

Let’s have a look at a quick example: say we have this hand:

If we called DoCardsHaveSameValue(hand, 2, info), the function would return true, because it found two queens. Also, the info object would have a new cardValues property that would be set to [12], because CardValues.QUEEN has a value of 12, and that was the value of the card that was found the two times we requested.

We need the value of the first element in the info.cardValues array from each hand to compare their pair values.

So, from CardMatchUtils.DoCardsHaveSameValue(hand1, 2, hand1Info) in our FindWinnerJacksOrBetter function, there will be a hand1Info.cardValues property you can now use. We’ll make use of these in the ComparePairs(hand1, hand1Info, hand2, hand2Info) function. See below:

ComparePairs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ComparePairs = function(hand1, hand1Info, hand2, hand2Info) {
  SET hand1WorkingPairValue = hand1Info.cardValues[0]
  IF (CardMatchUtils.CountCardsByValue(hand1, WILD_VALUE) GREATER OR EQUALS 2)
    hand1WorkingPairValue = ACE_VALUE
 
  SET hand2WorkingPairValue = hand2Info.cardValues[0]
  IF (CardMatchUtils.CountCardsByValue(hand2, WILD_VALUE) GREATER OR EQUALS 2)
    hand2WorkingPairValue = ACE_VALUE
 
  IF (hand1WorkingPairValue > hand2WorkingPairValue)
    RETURN 0 (hand 1 has the higher ranking pair)
  ELSE IF (hand1WorkingPairValue < hand2WorkingPairValue)
    RETURN 1 (hand 2 has the higher ranking pair)
  END
 
  RETURN -1 (both hands' pairs have the same rank)
}

Since we now have the values of the pairs in both hands, we could’ve just compared hand1Info.cardValues[0] to hand2Info.cardValues[0]. But instead, we performed an additional check if the hand contained at least two wild cards (see below), then assigned the working pair value to the ace value. That’s because if we did only a cardValues[0] comparison, that presents a problem when wild cards are involved.

Remember, to satisfy the requirements of CardMatchUtils.DoCardsHaveSameValue, a wild card assumes the value of the highest non-wild card. So if you had a hand like this:

The wild card would assume a value of a king, and you’d have a pair of kings.

But what if you had a hand with, not one, but TWO wilds in it!? (gasp o: )

Normally, one of the wilds would still try to assume the value of the highest non-wild card. in this case, it would be a 9, but this does not for a jacks-or-higher pair. Instead, we could simply have the two wilds themselves form the pair, and assume the highest non-wild value, which would be ace. So the pair of wilds acts like a pair of aces.

So, if the CountCardsByValue call finds two wild cards in the hand, the working pair value for that hand will be CardValues.WILD, instead of the value found in cardValues[0].

Note: You want to check if there are at least two wild cards, because, say hand 1 contained two wilds, and hand 2 contained three. The wilds in both hands would form a pair, and hand 2 would have an extra wild card left over. This third wild, however, is not involved in the pair, but would be a kicker, substituting as an ace.

Comparing the Kickers

If the pairs of both hands have the same rank, then we’ll need to compare the other three cards, the kickers, and see which hand, if either, is finally a winner.

When comparing the kickers, it would be great if we could first remove the pairs from both hands so we’re only left with the remaining three cards of each. This would also remove situations where the value of a pair might not be the highest value in the hand. The two cards that make up the pair aren’t necessarily at the beginning of the hand, (when ordered by descending card value). For example, the hand could contain a pair of queens, but the highest card is a king.

So, you can remove the cards that make up the pair (including wilds) by writing a new function to go into CardMatchUtils file. Let’s call this function BuildHandExcludingValues. This function will create a copy of a hand, with specific cards excluded from the copy. It takes three parameters:

  1. cards – The hand (an array of Card objects)
  2. valuesToExclude – An array of card values that are to be excluded from the new copy, if they are found in cards
  3. maxCountToExclude – The maximum count of cards that can be excluded. This is useful to prevent the function from excluding too many cards. For example, a hand may have three queens in it; we only want to remove two, and the third one is a kicker.

Without further ado, tis BuildHandExcludingValues function:

BuildHandExcludingValues
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BuildHandExcludingValues = function(cards, valuesToExclude, maxCountToExclude) {
  SET copyHand = [] (this is our new hand; set it up as an empty array)
  SET currentCountExcluded = 0 (keep track of the number of cards excluded)
 
  FOR EACH card IN cards
    IF (card.value does not match any of the values in valuesToExclude)
      add the card to the copyHand array
    ELSE
      IF currentCountExcluded LESS THAN maxCountToExclude
        increment currentCountExcluded by 1 (this card is effectively "excluded" from the copy)
      ELSE
        add the card to the copyHand array (the max number of excluded cards has been reach; include card in the copy, even if it's supposed to be excluded)
      END
    END
  END
 
  RETURN copyHand
}

Let’s have a look at two quick examples.

Say you have this hand:

Your pair would be the king and the wild (acting as the other king). Your kickers are the three remaining cards.

If you called BuildHandExcludingValues with valuesToExclude set to [ CardValues.KING, CardValues.WILD ], and maxCountToExclude set to 2, the copy returned would look like:

These are the three kickers.

Now, consider this hand:

After calling BuildHandExcludingValues with valuesToExclude set to [ CardValues.QUEEN ], and maxCountToExclude set to 2, the copy returned would look like:

In this case, the queens form a pair without using a wild, so the wild becomes a kicker that assumes the highest value (ace).

Before you compare the kickers of both hands, you’ll need to sort them in descending order, but this time, wilds will be placed first (as the highest value) instead of last like usual. You’ll use the new function CardMatchUtils.SortCardsByDescendingValueHighWilds that you wrote in the last article.

The comparison of the kickers can be made with another new function that you can place in CardMatchUtils: CardMatchUtils.CompareHands. You’ll see how this function works below.

CompareKickers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CompareKickers = function(hand1, hand1Info, hand2, hand2Info) {
  (build a temporary hand that contains only the kickers from hand 1)
  SET valuesToExclude = [ CardValues.WILD ]
  IF (CardMatchUtils.CountCardsByValue(hand1, WILD_VALUE) NOT EQUAL 2)
    add hand1Info.cardValues[0] to the valuesToExclude array
  SET hand1Kickers = CardMatchUtils.BuildHandExcludingValues(hand1, valuesToExclude, 2)
  hand1Kickers = CardMatchUtils.SortCardsByDescendingValueHighWilds(hand1Kickers)
 
  (build a temporary hand that contains only the kickers from hand 2)
  SET valuesToExclude = [ CardValues.WILD ]
  IF (CardMatchUtils.CountCardsByValue(hand1, WILD_VALUE) NOT EQUAL 2)
    add hand2Info.cardValues[0] to the valuesToExclude array
  SET hand2Kickers = CardMatchUtils.BuildHandExcludingValues(hand2, valuesToExclude, 2)
  hand2Kickers = CardMatchUtils.SortCardsByDescendingValueHighWilds(hand2Kickers);
 
  (compare the two temporary hands)
  SET winningPlayerIndex = CardMatchUtils.CompareHands(hand1Kickers, hand2Kickers)
  RETURN winningPlayerIndex
}
CompareHands
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CardMatchUtils.CompareHands = function(hand1, hand2) {
  (both hand1 and hand2 should contain the same number of cards in them, but if they don't, use the hand with fewer cards as the number of cards to
  compare)
  SET numberOfCardsToCompare = MIN(hand1.length, hand2.length)
 
  FOR cardIndex = 0 TO numberOfCardsToCompare
    (get the nth card from each hand)
    SET card1 = hand1[cardIndex]
    SET card2 = hand2[cardIndex]
 
    (get the card value of both cards to compare; treat wilds as aces)
    SET card1Value = MIN(card1.value, CardValues.ACE)
    SET card2Value = MIN(card1.value, CardValues.ACE)
 
    IF (card1Value GREATER THAN card2Value)
      RETURN 0 (hand 1 has a higher ranking hand)
    ELSE IF (card1Value LESS THAN card2Value)
      RETURN 1 (hand 2 has a higher ranking hand)
    END IF
  END
 
  (all cards in both hands are equal)
  RETURN -1
}

The CardMatchUtils.CompareHands function accepts two parameters: both players’ hands. The hands are the temporary ones that include only the kickers, and should already be sorted in descending order with wilds at the beginning of the order. The function compares cards in both hands, starting with each hand’s first card, then second if necessary, and so on. It returns 0 if hand1 has a higher hand, 1 if hand2 has a higher hand, or -1 if both hands are equal. The value returned gets passed back up to the function that called it, CompareKickers, which passes the returned value back up to the original calling function, FindWinnerJacksOrBetter.

That pretty much wraps it up for this article! When you have a physical deck of cards, and you compare two poker hands, it’s easy to determine which one wins. But when you have to write out the process for doing so, step by step, it’s a bit more challenging that you might realize. 😉

Compare Your Own Hands

You can use the controls below to build your own hands and compare pairs of jacks or better. Now that you have two poker hands, high card and jacks or better pairs, you can also compare those two ranks, and you’ll see that the pair will always beat the high card. Have some fun playing around with it, and if you find an issue, please let me know!


Player 1

Result:

Player 2

Result:

Player 3

Result:

Who Won:

If you have any questions about recognizing a royal flush, or the above interaction, please let me know at cartrell@gameplaycoder.com.

Thanks, and stay tuned, because we have more poker hands to cover in this series!

– C. out.

How to Code Poker Hands – Comparing Hands For A High Card

Welcome!

The last article introduced you to writing code to compare two poker hands. You learned that when comparing poker hands of different ranks, the one with the higher rank wins (a full house beats a three of a kind). But what happens when you have poker hands that are the same rank? 🤔

In this article you’ll learn how to compare the lowest ranking poker hand, a high card.

A high card hand doesn’t fall into any of the other categories, such as a pair, two pair, three of a kind, straight, etc. When determining the type of hand, if it doesn’t match any of the poker hands, it’s automatically a high card hand.

When you compare high card hands, the one with the highest ranking card wins. If they have the same highest ranking card, then you compare the next highest-ranking card and so on.

Before comparing hands, sorting the cards in order of descending rank first makes the comparisons much easier. But instead of putting wild cards at the end, they’ll go at the beginning. We’ll cover this in more details later in this article.

Let’s have a look at these two hands:

As you can see, the first four cards both hands are of the same value. We get to the final card, and the second hand’s three beats the first hand’s two. So, the second high card hand beats the first one.

Setup

Note: The first stages of the setup can be found on the introduction page to comparing poker hands here.

In many of the hand comparisons, wild cards can be treated as the highest card value, because they can assume any value. So, it will assume the highest card value possible while still satisfying the poker hand (this would’ve already been determined when matching the poker hand). You may recall when matching poker hands, we sorted the cards in descending order, with the wild cards as the lowest value, ordering them at the end of the sorted hand. However, when comparing poker hands, the wild cards will be the highest value, ordering them at the beginning of the sorted hand.

From there, you’ll need a new, albeit simpler sort function. And because this sort will be used by multiple poker hand comparisons, you can put it in your CardMatchUtils class as a function:

SortCardsByDescendingValueHighWilds
1
2
3
4
CardMatchUtils.SortCardsByDescendingValueHighWilds = function(hand) {
  var sortedHand = hand.concat();
  sortedHand.sort(CardMatchUtils.OnSortCardsByDescendingValueHighWilds);
}
OnSortCardsByDescendingValueHighWilds
1
2
3
4
5
6
7
8
9
function CardMatchUtils.OnSortCardsByDescendingValueHighWilds(card1, card2) {
  if (card1.value < card2.value) {
    return(1);
  } else if (card1.value > card2.value) {
    return(-1);
  }
   
  return(0);
}

In the main function, SortCardsByDescendingValueHighWilds, a copy of the hand parameter, which is an array of Card objects.

The sort function is called on the array, along with a callback function, OnSortCardsByDescendingValueHighWilds, that specifies how the cards should be ordered. When this function returns a number greater than zero, card2 should be placed before card1 (card2 has a higher value). If the function returns a number less than zero, card1 should come first. And if the function returns zero, then both cards have equal value, and their sort order against each other doesn’t matter.

Writing The Code For Comparing High Card Hands

Since this article focuses on the high card hand only, it assumes that from the GetWinningHand function, the poker hands are the same rank, which happens to be the high card.

The GetWinningHand function will eventually call FindWinnerHighCard to compare two high card hands. FindWinnerHighCard is the main topic of discussion for this article. It accepts two parameters, the hand for both players, and it’ll return the ID of the player who has the winning high card hand. If both hands are equal, it’ll return 0 (which we’ll use to mean a draw). So let’s dive in with some pseudocode. 🙂

FindWinnerHighCard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FindWinnerHighCard = function(hand1, hand2) {
  sortedHand1 = CardMatchUtils.SortCardsByDescendingValueHighWilds(hand1);
  sortedHand2 = CardMatchUtils.SortCardsByDescendingValueHighWilds(hand2);
   
  FOR (index = 0; index < sortedHand1.length; index++) {
    card1 = sortedHand1[index];
    card2 = sortedHand2[index];
     
    IF (card1.value > card2.value)
      RETURN PlayerId1;
    ELSE IF (card1.value < card2.value)
      RETURN PlayerId2;
    END
  }
   
  RETURN 0;
}

This function first sorts the cards in descending card value, with wild cards ordered first. Next, it compares the first card of each hand to determine the winner. If both cards are the same, it compares the second card, and so on. It does this until it finds a winning card, or all cards in both hands have been compared. If the latter is the case, then both cards are of equal rank, and the function returns 0.

That’s pretty much it for comparing two hands for the highest card. ✔

Compare Your Own Hands

You can use the controls below to build your own hands and compare high cards. Have some fun playing around with it, and if you find an issue, please let me know!


Player 1

Result:

Player 2

Result:

Player 3

Result:

Who Won:

If you have any questions about recognizing a royal flush, or the above interaction, please let me know at cartrell@gameplaycoder.com.

That’s it for now! Thanks, and the next article in the series will cover comparing hands that have a pair of jacks or higher.

– C. out.

How to Code Poker Hands – Comparing Hands

Now that the poker hands have been covered, there is another set of functionality to cover. When two poker hands are compared, which one wins?

This series presented the hands in order of lowest rank to highest rank. So they are ranked like this:

  1. Pair (Jacks or higher)
  2. Two pair
  3. Three of a kind
  4. Straight
  5. Flush
  6. Full house
  7. Four of a kind
  8. Straight flush
  9. Royal flush

In earlier articles, you may have noticed in the “Build Your Own Hand” section that you could have a four of a kind, which is also a three of a kind, or even a pair. But the four of a kind was the result. This is because a four of a kind ranks higher than a three of a kind, which ranks higher than and a pair.

Or you may have formed a full house, which is also a pair, a three of a kind, and even a two pair. The full house beats the three of a kind, which beats the two pair, which beats the pair.

This is happening because even if a hand contains multiple matches, the highest ranking one will always be picked. The next set of articles of the poker hand-matching series cover writing game code to determine the highest ranking poker hand between two hands.

If I may digress for a moment, the new “Build Your Own Hand” will look something like this, so you can compare two hands to each other:

You could do something like this, by adding all the previous psuedocode function for matching poker hands, and running them on the player’s hand. You’d run them in order of highest to lowest rank, because you want to find the first poker hand that matches the player’s hand.

Have a look at this code:

GetPokerHand
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GetPokerHand = function(hand) {
  IF RoyalFlush(hand)
    RETURN PokerHandIds.RoyalFlush
  ELSE IF StraightFlush(hand)
    RETURN PokerHandIds.StraightFlush
  ELSE IF FourOfAKind(hand)
    RETURN PokerHandIds.FourOfAKind
  ELSE IF FullHouse(hand)
    RETURN PokerHandIds.FullHouse
  ELSE IF Flush(hand)
    RETURN PokerHandIds.Flush
  ELSE IF Straight(hand)
    RETURN PokerHandIds.Straight
  ELSE IF ThreeOfAKind(hand)
    RETURN PokerHandIds.ThreeOfAKind
  ELSE IF TwoPair(hand)
    RETURN PokerHandIds.TwoPair
  ELSE IF JacksOrBetterPair(hand)
    RETURN PokerHandIds.JacksOrBetterPair
  END
 
  RETURN PokerHandIds.HighCard
}

The above code will return a value that tells you what type of poker hand the players hand is. But, look at these PokerHandIds.HandIsRoyalFlush, PokerHandIds.HandIsStraightFlush, and such pieces. What are those?

There needs to be a way to uniquely identify each poker hand, hence these “poker hand IDs”. You’ll assign each poker hand a unique ID. This brings us to the first part of the setup.

Setup
Poker Hand IDs

Let’s create a new data object, PokerHandIds, and similar to CardValues and CardSuits, we’ll assign it some properties.

1
2
3
4
5
6
7
8
9
10
11
12
PokerHandIds = {
  HighCard: 0,
  JacksOrBetterPair: 1,
  TwoPair: 2,
  ThreeOfAKind: 3,
  Straight: 4,
  Flush: 5,
  FullHouse: 6,
  FourOfAKind: 7,
  StraightFlush: 8,
  RoyalFlush: 9
};

Note: The HighCard means a hand that is not any poker hand. It’s of the lowest value, and the GetPokerHand function defaults to returning HighCard if the specified hand doesn’t match any of the poker hands.

Writing The Code To Compare Poker Hands

So you might be able to see where this is going. To compare two poker hands to find the higher-ranking one, you get the poker hand ID of both hands, then compare those IDs.

Say you have two players and their hands are stored in hand1 and hand2. The code for matching them might look something like this:

GetWinningHand
1
2
3
4
5
6
7
8
9
10
11
12
GetWinningHand = function(hand1, hand2) {
  hand1PokerId = GetPokerHand(hand1);
  hand2PokerId = GetPokerHand(hand2);
 
  IF (hand1PokerId > hand2PokerId)
    RETURN PlayerId1 ("player 1 wins")
  ELSE IF (hand2PokerId > hand1PokerId)
    RETURN PlayerId2 ("player 2 wins")
  END
 
  RETURN GetWinningPlayerId(hand1, hand2, hand1PokerId)
}

Note: The PlayerId1 and PlayerId2 are just used to uniquely identify which player we are referring to.

If one ID is bigger than the other, it’s pretty easy to determine which player wins. But what if both hands are the same rank, for instance, both are flushes, or both are two pairs? It’s not necessarily a “draw”, because you’ll need to do some additional checking on each hand to determine which flush, for example wins, or which two pair wins. And this type of comparison depends on the poker hand.

This new GetWinningPlayerId function accepts three parameters: both players’ hands, and the poker hand ID. (It doesn’t matter if you use either hand1PokerId or hand2PokerId, because they’re both the same.) And GetWinningPlayerId looks like:

GetWinningPlayerId
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GetWinningPlayerId = function(hand1, hand2, pokerHandId) {
  IF pokerHandId EQUALS PokerHandIds.HighCard
    RETURN FindWinnerHighCard(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.JacksOrBetterPair
    RETURN FindWinnerJacksOrBetterPair(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.TwoPair
    RETURN FindWinnerTwoPair(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.ThreeOfAKind
    RETURN FindWinnerThreeOfAKind(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.Straight
    RETURN FindWinnerStraight(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.Flush
    RETURN FindWinnerFlush(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.FullHouse
    RETURN FindWinnerFullHouse(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.FourOfAKind
    RETURN FindWinnerFourOfAKind(hand1, hand2)
  ELSE IF pokerHandId EQUALS PokerHandIds.StraightFlush
    RETURN FindWinnerStraightFlush(hand1, hand2)
  END IF
 
  RETURN FindWinnerRoyalFlush(hand1, hand2)
}

Depending on which player’s hand won, GetWinningPlayerId would return either PlayerId1 or PlayerId2.

It is also possible that both player hands, could the same rank, in cards, as well as poker hand. In that case, the match up really is a draw. So GetWinningPlayerId would return neither PlayerId1 nor PlayerId2, but Draw.

And these FindWinner... functions is where all the real fun of finding which poker had wins is! 😉 And like matching poker hands, you’ll be learning those in the next set of articles. So stay tuned for more!

That’s it for now. Talk you next time, and take care,

– C. out.

How to Code Poker Hands – Royal Flush

Well, if you’ve read the entire series, congrats! You’ve reached the final poker hand we’re covering, the royal flush! ⭐

A royal flush is a specialized version of the straight flush, so let’s quickly go over the straight flush first.

A straight flush is a combination of a straight and a flush. A straight is where the cards are in sequential order by value, and there are least two different suits among the cards. And a flush is where all cards in the hand have the same suit, and are not in sequential order by value.

So then, a straight flush is a hand where the cards are in order by rank, and they all have the same suit.

Now, back to the royal flush. It’s a special type of straight flush where the highest card is an ace. The image featured at the top of this article is a royal flush.

Before continuing, you can review the poker hands that have already been covered by following any of the links below:

Setup

If you’ve been following the series, you’ve probably got this part burned into your memory by now, haha! Of course, they are briefly discussed here, but you check out this link . Otherwise, if you’d like to skip ahead, check here.

Card Values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CardValues = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 11,
  queen: 12,
  king: 13,
  ace: 14,
  wild: 100
};
Card Suits
1
2
3
4
5
6
CardSuits = {
  hearts: 1,
  diamonds: 2
  clubs: 3,
  spades: 4
};
Card
1
2
3
4
Card = function(value, suit) {
  this.value = value;
  this.suit = suit;
};
Hand

And a hand is an array of Card objects:

1
2
3
4
5
6
var hand = [
  new Card([card value 1], [card suit 1]),
  new Card([card value 2], [card suit 2]),
  ...
  new Card([card value 5], [card suit 5])
];
Writing The Code To Identify A Straight Flush

We’ll start with writing code for a straight flush, because it’s a easier than the royal flush. The pseudocode for matching a straight flush looks like:

Straight Flush
1
2
3
4
5
6
7
8
9
10
StraightFlush = FUNCTION(hand) {
  SORT the hand by descending card value and store in a variable called sortedHand
 
  IF AreCardsStraight(sortedHand) AND AreCardsFlush(sortedHand)
    //we have a straight flush!
    RETURN TRUE
 
  //no straight flush in this hand
  RETURN FALSE
}

Most of the code has already been written, thanks to the CardMatchUtils file that contains three functions:

If you’re new to the series, we previously defined a “utilities” file, named CardMatchUtils.js. This file is shared by all the poker hand matching functions, because it contains a several functions that they all use, and sorting the cards by their descending value makes performing the card-matching functions much easier.

So after sorting the cards in the hand, you want to check if the cards are both a straight and a flush. If so, the hand is a certifiable straight flush. Super easy 😎

Royal Flush

As I mentioned before, a royal flush is a special version of the straight flush, where the ace is the high card.

The royal flush would be a simple modification of adding a check to see if the first card of the sorted hand is an ace, and if so, you’d have a royal flush. However, we’re using wild cards, and they will throw a 🐒 🔧 into that plan.

First, let’s consider this hand:

Once you’ve successfully determined that the hand is a straight flush, check the first card. As long as it’s an Ace, you’re good to go.

Because wild cards are already handled in both CardMatchUtils.AreCardsStraight AND CardMatchUtils.AreCardsFlush, you don’t need to do anything specific for wild cards here.

However, what if you had a straight flush where the high card is not an ace, and wilds are present instead? Consider these hands:

All of these hands are royal flushes because of the wild cards!

If you look at what’s going on, for each wild card in the hand, the high card is the value of the ace, minus the number of wild cards in the hand. For example, if there is one wild, the high card (the first card in the hand) must be ace – 1 = king. You can use the numeric values defined in CardValues to do the math. If there are, say three wilds, the high card must be ace – 3 = jack.

However, for the last hand with five wilds, this won’t work. If you took ace – 5, we’d have 9. And the high card is a wild, and CardValues.nine != CardValues.wild.

Back when you setup CardValues, you gave CardValues.wild an arbitrary, super-high numeric value (in this case, 100). So when checking that high card, you’ll want to use a greater-than-or-equal-to comparison, instead of equal-to.

So, the royal flush pseudocode looks like this:

RoyalFlush
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
RoyalFlush = FUNCTION(hand) {
  SORT the hand by descending card value and store in a variable called sortedHand
 
  IF NOT AreCardsStraight(sortedHand) OR NOT AreCardsFlush(sortedHand)
    //no royal flush in this hand - must be both straight and flush to be considered
    RETURN FALSE
 
  get number of wilds in the hand and store in a variable called numWilds
  get the max card value by subtracting numWilds from the ace value (CardValues.ace) and store in a variable called maxCardValue
  get the first card in the sorted hand (array)
  IF the value of this card is GREATER THAN OR EQUAL TO maxCardValue
    //this hand is a royal flush
    RETURN TRUE
 
  //no royal flush in this hand
  RETURN FALSE
}
Build Your Own Hand

You can use the controls below to create your own hand to see if it is a royal flush or a straight flush. It will also recognize previous poker hands we’ve covered up to this point. Have fun playing around with it!


Result: JACKS OR BETTER

If you have any questions about recognizing a royal flush, or the above interaction, please let me know at cartrell@gameplaycoder.com.

That’s all for this article, and also for the poker hands series. Congrats for getting through all of them! ⭐⭐ You should now have a solid idea on how to write code to identify poker hands in a five-card hand.

Thanks, and stay tuned for more articles!

– C. out.

How to Code Poker Hands – Four Of A Kind

Hello!

You’ve seen the pair (two of a kind), three of a kind, so guess what’s coming next?

Yep… four of a kind! (:

Programming the match for this hand is very similar to that of a three of a kind.

Ok first, you can review the poker hands that have already been covered by following any of the links below:

Setup

Before we begin writing the main code, here are some data structures you’ll be using. They are briefly discussed here, but if you’d like the full details, check out this link. Otherwise, if you’d like to skip ahead, please click here.

Card values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CardValues = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 11,
  queen: 12,
  king: 13,
  ace: 14,
  wild: 100
};
Card suits
1
2
3
4
5
6
CardSuits = {
  hearts: 1,
  diamonds: 2
  clubs: 3,
  spades: 4
};
Card
1
2
3
4
Card = function(value, suit) {
  this.value = value;
  this.suit = suit;
};
Hand

A “hand” is not a custom data structure like the ones above, but an array of Card objects:

1
2
3
4
5
6
var hand = [
  new Card([card value 1], [card suit 1]),
  new Card([card value 2], [card suit 2]),
  ...
  new Card([card value 5], [card suit 5])
];
Writing The Code To Identify A Four Of A Kind

A four of a kind is similar very much like a three of a kind. We’re looking for four cards of the same value (rank) instead of three.

First, sort the cards by their rank, in descending order. We previously defined a “utilities” file, named CardMatchUtils.js, and added a function to it called, CardMatchUtils.SortCardsByDescendingValue, which can perform the sorting. If you’re just joining this series, CardMatchUtils.js is a file that is shared by all the poker hand matching functions, because it contains a several functions that they all use. CardMatchUtils.SortCardsByDescendingValue is one of those functions, because sorting a hand by the ranks of its cards in descending order helps to make the poker hand matching much easier.

The CardsHaveSameValue utilities function, previously written here, determines if a certain number of cards in the hand have the same rank. In this case, we want to check for four cards.

We’re also using the “wild card”, which is a card that can assume the rank of any card. So, the following hand would also qualify as a four of a kind:

After sorting the cards by their card rank in descending order, the hand looks like:

Wild cards are always sorted at the end of the hand.

There are a pair of fives already, and the two wilds will assume another pair of fives.

The pseudocode for matching a four of a kind looks like:

1
2
3
4
5
6
7
8
9
10
FourOfAKind = FUNCTION(hand) {
  SORT the hand by descending card value and store in a variable called sortedHand
 
  IF CardsHaveSameValue(sortedHand, 4)
    //we have a three of a kind!
    RETURN TRUE
 
  //no four of a kind in this hand
  RETURN FALSE
}

The CardsHaveSameValue function does most of the work here, and you can review that function to see how it functions.

Build Your Own Hand

You can use the controls below to create your own hand to see if it is a four of a kind. It will also recognize previous poker hands we’ve covered up to this point. Have fun playing around with it!


Result:

If you have any questions about recognizing a four of a kind, or the above interaction, please let me know at cartrell@gameplaycoder.com.

That’s all for this article. Thanks, and stay tuned as this series continues!

– C. out.

How to Code Poker Hands – Full House

Hey there,

We’re almost done with coding solutions for determining the various hands in the card game of poker. In this article, you’ll learn how to code the solution for the full house.

A full house is a hand that contains a pair of cards on one value (rank), and a three of a kind of another value.

You can check out the poker hands that have already been covered, using the links below:

Setup

Continuing the trend in the series, yep, you guessed it, the code setup has not changed. 🙂

A brief summary of the setup is below. If you’d like to skip ahead of this section, click here. If you want to see the full details of the setup, check out this link.

Card Values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CardValues = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 11,
  queen: 12,
  king: 13,
  ace: 14,
  wild: 100
};
Card Suits
1
2
3
4
5
6
CardSuits = {
  hearts: 1,
  diamonds: 2
  clubs: 3,
  spades: 4
};
Card
1
2
3
4
Card = function(value, suit) {
  this.value = value;
  this.suit = suit;
};
Hand

A hand is an array of Card objects:

1
2
3
4
5
6
var hand = [
  new Card([card value 1], [card suit 1]),
  new Card([card value 2], [card suit 2]),
  ...
  new Card([card value 5], [card suit 5])
];
Writing The Code To Identify A Full House

Although the full house is essentially a pair and a three of a kind combined into one hand, it’s a little more of a challenge, especially when wild cards are involved.

Just as with coding solutions for the other poker hands, first make sure the cards in your hand are sorted by descending value.

Also, we’ll be using the utilities class, CardMatchUtils. This is the class we’ve been building that contains common functionality used across all poker hands.

There are two specific functions that CardMatchUtils will use:

Now let’s get into some pseudo code! 😎

The function takes one parameter, sortedHand which a hand that has already been passed to CardMatchUtils.SortCardsByDescendingValue, and the result being used as this parameter.

Writing out the main function for a full house looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
AreCardsFullHouse = FUNCTION(sortedHand) {
  //check for an x-x-x-y-y full house
  IF the first three cards have the same value AND the last two cards have the same value, but different from the first three
    RETURN TRUE (this hand has a full house)
  END IF
 
  //check for an x-x-y-y-y full house
  IF first two cards have the same value AND the last three cards have the same value, but different from the first two
    RETURN TRUE (this hand has a full house)
  END IF
 
  RETURN FALSE (this hand does not form a full house)
}

When the cards are sorted by descending value, there are two possible combinations for a full house. The first one is if the three of a kind comes first, followed by a pair, and it looks like this:

The second combination is if the pair comes first, followed by the three of a kind:

And if you have a wild card with a two pair, that also forms a full house:

The wild could assume a value of 10, thus forming a three of a kind, which is followed by the pair. Wild cards are always placed at the end of the hand when sorted.

Also, because of those blasted wild cards (damn you, (: ), they can be used in either the three of a kind or the two pair, and we need to keep track of who many wild cards are left remaining, while the AreCardsFullHouse function is running.

CardMatchUtils.DoCardsHaveSameValue is a function that determines if a certain number of cards in the hand have the same value. The function takes three parameters:

  • sortedHand – The hand, already assumed to be sorted in descending order by card rank.
  • numToMatch – The number of cards that must have the same value.
  • wildsInfo – An object that stores information about the wild cards.

The wildsInfo parameter is used to save information for multiple calls to CardMatchUtils.DoCardsHaveSameValue. First declare an empty object { }. The first time you call the function, you’d pass in this empty object. On subsequent calls to CardMatchUtils.DoCardsHaveSameValue, you’d pass in the same object.

While CardMatchUtils.DoCardsHaveSameValue is running, it creates two properties on the wildsInfo object:

  • numWilds – The number of wild cards available for use as substitutes.
  • startIndex – The index of the sortedHand array on which DoCardsHaveSameValue starts when it checks each card in the hand.

These properties are modified and saved while CardMatchUtils.DoCardsHaveSameValue runs. Each subsequent call to this function continues where the previous one left off. For example, if the hand contains one or more wild cards and at least one was used to, say, form a three of a kind, the numWilds will be updated for use in the next call to CardMatchUtils.DoCardsHaveSameValue.

The CardMatchUtils.DoCardsHaveSameValue function is explained in detail here, and you can go back to review it if you want. It’s a rather long one, but it does the brunt of the work of checking for a full house.

Build Your Own Hand

You can use the controls below to create your own hand to see if it is a full house. It will also recognize previous poker hands we’ve covered up to this point. Have fun playing around with it! ⭐


Result:

If you have any questions about recognizing a full house hand, the above interaction, or any of the other poker hands, please let me know at cartrell@gameplaycoder.com.

Finally, if you’d like to hire me to program an actual card game for you, please e-mail me, or use the contact form here.

That’s all for this article. Thanks, and stay tuned as we are almost finished with this series! 💪🏾

– C. out.

How to Code Poker Hands – Flush

Hey there,

In this article, we’re continuing the series of writing code that recognizes the various poker hands. Today, you’ll build the solution for a hand that matches a flush.

A flush is a hand where all five cards are of the same suit, but not in order of sequential rank.

If you’d like to see poker hands that have already been covered, please check the links below.

Setup

The code setup is the same as in the previous articles of this mini-series. A quick rundown of the setup is below, but if you’d like to skip ahead, check here. If you’d like to see the full details of the setup, check out this link.

Card Values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CardValues = {
  two: 2,
  three: 3,
  four: 4,
  five: 5,
  six: 6,
  seven: 7,
  eight: 8,
  nine: 9,
  ten: 10,
  jack: 11,
  queen: 12,
  king: 13,
  ace: 14,
  wild: 100
};
Card Suits
1
2
3
4
5
6
CardSuits = {
  hearts: 1,
  diamonds: 2
  clubs: 3,
  spades: 4
};
Card
1
2
3
4
Card = function(value, suit) {
  this.value = value;
  this.suit = suit;
};

And a hand is an array of Card objects:

1
2
3
4
5
6
var hand = [
  new Card([card value 1], [card suit 1]),
  new Card([card value 2], [card suit 2]),
  ...
  new Card([card value 5], [card suit 5])
];
Writing The Code To Identify A Flush

As mentioned before, a flush is a hand where all the cards have the same suit, but their ranks are not in sequential order. Now, programming the flush is one of the easier poker hands to match, because all you’re doing is checking that all the cards have the same suit, using the first card’s suit as the criteria.

But remember, we’re also using “wild cards” here. So far you’ve used them to assume any value (rank), but in the case of a flush, a wild card can also assume any suit.

You don’t necessarily need to sort the cards by descending rank, since the flush is not a value-based hand. However, doing so will programming the matching logic a little easier.

Like you did with the previous hand, the straight, you’ll be adding a function to the “utilities” file, CardMatchUtils.js. In an upcoming article, you’ll program the straight flush, which is a combination of the straight and the flush. So, you’ll add a new function, CardMatchUtils.AreCardsFlush, CardMatchUtils, which will be used by both hands.

There are two functions that CardMatchUtils will use:

  1. CardMatchUtils.SortCardsByDescendingValue – This function sorts the cards in the hand by descending value. This orders the cards from highest value to lowest.
  2. CardMatchUtils.AreCardsFlush – This function has not yet been written (but that’s what you’ll write in this article! 🙂 ) This function will be used in recognizing both, the flush, and the straight flush poker hands.

And without further ado, let’s get into some pseudocode for the flush! It looks like this:

1
2
3
4
5
6
7
8
9
10
Flush = FUNCTION(hand) {
  SORT the hand by descending card value and store in a variable called sortedHand
 
  IF AreCardsFlush(sortedHand)
    //we have a flush hand
    RETURN TRUE
 
  //this hand is not a flush
  RETURN FALSE
}

This function looks very similar to the AreCardsStraight function from the last article. The bulk of the details is in the AreCardsFlush function. Let’s now have a look at its pseudocode:

AreCardsFlush
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
AreCardsFlush = FUNCTION(sortedHand) {
  FOR EACH card in the sortedHand {
    IF this card (the current loop card) is the first card being checked {
      set a variable called baseCardSuit to the suit of this card
      re-start FOR loop again with next card (in other words, "continue" if you're familiar with for-loops)
    }
 
    IF this card is a wild card {
      RETURN TRUE (since cards are already sorted, once we get to a wild card we're done; all preceding cards match the base card suit)
    }
 
    IF the suit of this card EQUALS the value of baseCardSuit {
      re-start FOR loop again with next card
    } ELSE {
      RETURN FALSE (suit of this card doesn't match the vase card suit - this hand is not a flush)
    }
  }
 
  RETURN TRUE (all cards have the same suit)
}

This code gets the suit of the first card in the sorted hand, and compares it to the suit of every other card. As long as they match, the loop will continue until it reaches the end, or encounters either a wild card (success), or a card whose suit doesn’t match that of the first card’s (failure).

Say you have a hand that looks like this (after sorting all cards in descending value order, with wild cards at the end):

The first card is the king of hearts, so the “base card suit” will be assigned to value CardSuits.diamonds.
The suit of the second card is spades, which does not match diamonds. So, this hand is not a flush.

Now say we had this hand:

The base card suit is the spade, from the jack of spades. The next two cards are also spades. So far so good. Then then fourth card is a wild. At this point, you can say that this hand is a flush. The cards are already sorted with wilds at the end, and because wilds can assume any suit (in this case, spades), so they will complete the flush. There is no need to continue checking the cards, because they will all be wilds. This is how sorting helps simplify recognizing a flush.

Not too much more to say about programming a flush, since it’s one of the easier hands to identify – even easier than a 🍐, in my opinion.

Build Your Own Hand

You can use the controls below to create your own hand to see if it is a flush or not. It will also recognize previous hands we’ve covered up to this point. Have fun playing around and making various hands!


Result:

If you have any questions about recognizing a flush hand, or the above interaction, please let me know at cartrell@gameplaycoder.com.

Finally, if you’d like to hire me to program an actual card game for you, you can e-mail me, or you may use the contact form here.

That’s it for today. Thanks, and stay tuned because we more poker hands to program. The next one will be the full house!

– C. out.