When you have two poker hands, and both are a four of a kind, how can you determine which one ranks higher? In this article, you’ll learn how to code a solution.
A previous article for poker hands demonstrated how to compare a hand to determine if it was four of a kind. A four of a kind is hand where four of the cards are the same value, and the remaining card is a different value. It’s like a three of a kind, but instead of matching three cards, it matches four. Here’s an example of a four of a kind:
Also, the comparison process is very similar to a comparing threes of kinds:
- Compare the values of the quadruplet (the four cards that have the same value).
- If those values are equal, compare the values of other the kickers, which is the card that has the other value.
- If no kicker breaks the tie, and all cards have been compared, then both hands are equal.
Let’s look at some examples:
Hand 1 has a quad value of 5, while hand 2 has a quad value of 3. Since 5 is greater than 3, hand 1 is the higher four of a kind.
If the quad values of both hands are the same, then you compare the kicker card. Check this out:
Both hands had a quad value of queen. Hand 1 has a kicker value of king, while hand 2’s kicker value is ace. Ace beats king, so hand 2 is the winner here.
And one more thing before we get into the code – the wild cards (:
But handling wild cards in comparing a four of a kind is similar to that of a three of a kind. Take these hands:
In hand 1, the wild card is swapped for a 2 to form a four of a kind. The kicker value is a queen. For hand 2, it already has a four of a kind from the twos, so you can use the wild card to substitute the highest possible value, an ace.
When comparing both hands, hand 2 wins, because it has the higher kicker value (ace winning over queen).
Note: In hand 1, you could’ve substituted also the wild with the highest possible value, ace. But then, it would no not form a four of a kind, but a three of a kind. You also could’ve substituted it with another queen to form a full house, twos over queens, but a full house ranks lower than a four of a kind. So, substituting the wild for as a two produces the highest possible hand.
On a side note, in hand 2, you could’ve substituted the wild as a two, forming a five of a kind, which ranks higher than a four of a kind. However, we won’t be covering fives of kinds in this series. I’ll leave it as a challenge to you, should you accept it (: If you’re interested, you can learn a little more about a five of a kind here.
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 Fours Of Kinds
When two hands are both a three of a kind, the GetWinningHand
function will call a function that compares two hands of said poker hand.
In this case, GetWinningHand
function will eventually call FindWinnerFourOfAKind
(shown below) to compare the hands. This function 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 indicate a draw). The pseudocode below starts by comparing the values of the pairs first, then comparing the kickers if necessary.
FindWinnerFourOfAKind
FindWinnerFourOfAKind = function(hand1, hand2) {
sortedHand1 = CardMatchUtils.SortCardsByDescendingValue(hand1);
SET hand1Info to an empty object { }
CardMatchUtils.DoCardsHaveSameValue(hand1, 4, hand1Info);
sortedHand2 = CardMatchUtils.SortCardsByDescendingValue(hand2);
SET hand2Info to an empty object { }
CardMatchUtils.DoCardsHaveSameValue(hand2, 4, hand2Info);
SET winningIndex = CompareQuads(hand1, hand1Info, hand2, hand2Info);
IF (winningIndex NOT EQUAL TO -1)
RETURN winningIndex (one hand's quad outranks the other hand's, and no further checking is necessary)
END
(both hands have the same ranking quad, now compare the kickers of both hands)
SET winningIndex = CompareKickers(hand1, hand1Info, hand2, hand2Info);
RETURN winningIndex;
}
Like most poker hand matching and comparing functions, you’ll need to first sort the cards in descending order of value (highest to lowest) before processing. This helps tremendously in the code. Yeah, you and I could just “look” at a couple hands and see the winner, but code? Not so much. 🙃
If you already read the article for comparing threes of kinds, this function looks very similar to FindWinnerThreeKind
!
(Psst, here’s the big secret! 🐱👤 You catch a break with comparing fours of kinds. It’s mostly a copy-paste job, changing threes to fours, and replacing “trios” with “quads”)
Comparing The Quadruplets
In the FindWinnerFourOfAKind
function, the code above sets the hands up for comparing their quadruplets. It then sorts the cards or descending order by card value. Next, it uses the DoCardsHaveSameValue
function to get the four cards in the hand that make the quad, as well as determine the quad’s value.
CompareQuads
CompareQuads = function(hand1, hand1Info, hand2, hand2Info) {
SET hand1WorkingQuadValue = hand1Info.cardValues[0]
IF (CardMatchUtils.CountCardsByValue(hand1, WILD_VALUE) GREATER OR EQUALS 4)
hand1WorkingPairValue = ACE_VALUE
END
SET hand2WorkingQuadValue = hand2Info.cardValues[0]
IF (CardMatchUtils.CountCardsByValue(hand2, WILD_VALUE) GREATER OR EQUALS 4)
hand2WorkingQuadValue = ACE_VALUE
END
IF (hand1WorkingQuadValue > hand2WorkingQuadValue)
RETURN 0 (hand 1 has the higher ranking quad)
ELSE IF (hand1WorkingQuadValue < hand2WorkingQuadValue)
RETURN 1 (hand 2 has the higher ranking quad)
END
RETURN -1 (both hands' quads have the same value)
}
This function is very similar to the CompareTrios
function in our recent article for comparing threes of kinds, except instead of dealing with three cards, we’re dealing with four. If you’d like details on the workings of that function, please check here.
Comparing The Kickers
If the quads of both hands have the same value, then you’ll need to compare the final card in each hand, its kicker.
Like you did when comparing the kickers with previous poker hands, when comparing the kickers, you first remove the quads from both hands so you’re left with the remaining kicker. You can use the CardMatchUtils.BuildHandExcludingValues
function to remove the quad.
GetKickers
GetKickers = function(hand, info) {
(get the value of the cards that form the quad)
SET quadCardValue = info.cardValues[0]
(count the number of cards in the hand that match the quad card value)
SET numQuadValueCards = CardMatchUtils.CountCardsByValue(hand, quadCardValue)
(if there are at least as many quad value cards as there are non-kicker cards, specify the quad card value to the values of cards to exclude)
SET numNonKickerCards = 4
IF numQuadValueCards >= numNonKickerCards
SET valuesToExclude = quadCardValue
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 quad card value and the wild card value as the values of cards to exclude)
SET valuesToExclude = [ CardValues.WILD, quadCardValue ]
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 FindWinnerFourKind
. It’s either 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 quad card value used to form the four of a kind. Cards of this value obviously can’t be the kickers. This means they’ll be excluded, leaving the remaining card as the kicker.
The second situation is a hand that contains at least four wilds cards. These cards can assume the highest non-wild value, which is an ace. So the four wilds would form the four of a kind, using an ace as the quad card value. So the wild card value itself would be excluded from the hand of kickers.
Finally, the hand doesn’t have four cards with the same value, but it does contain one of the following combinations:
- One wild and a triplet
- Two wilds and a pair
- Three wilds and the higher non-kicker of the remaining two cards
Note: When excluding cards, you’re always excluding exactly four cards (the number of non-kicker cards).
Those wilds will assume the value of the whatever the quad value is, forming the four of a kind. In this situation, you want to exclude both values of both, the wild card, and the quad card value.
The GetKickers
function from above helps with this.
CompareKickers
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, 1
if hand2 has the better kickers, or -1
if both hands are the same rank.
That’s pretty much it! 😎
Compare Your Own Hands
You can use the controls below to build your own hands and compare fours of kinds. Have fun playing around with it!
Player 1
Player 2
Player 3
If you have any questions about anything in this article, please let me know at cartrell@gameplaycoder.com.
Thanks and take care,
– C. out.