Hand Evaluation
Relevant source files
The following files were used as context for generating this wiki page:The Hand Evaluation system is a core module of the poker engine responsible for determining the strength and rank of a player's poker hand. It analyzes a set of cards to identify the best possible 5-card combination and assigns it a numerical value for comparison. This system is crucial for the determineWinners function, which resolves the outcome of a hand at showdown. The engine supports evaluation for both Texas Hold'em and Omaha game modes, each with its specific rules.
Sources: lib/poker-engine.ts:111-124, 401-432, types/poker.ts:10-21
Core Data Structures
The evaluation logic relies on several key data structures defined in types/poker.ts. The primary structure is HandEvaluation, which encapsulates the result of an evaluation.
Sources: types/poker.ts:1-21
HandEvaluation Interface
This interface represents the outcome of evaluating a 5-card hand.
| Field | Type | Description |
|---|---|---|
rank | HandRank | The classification of the hand (e.g., "pair", "flush"). |
value | number | A numerical score representing the hand's strength for easy comparison. |
cards | Card[] | The 5 cards that form the evaluated hand, typically sorted by rank. |
description | string | A human-readable description of the hand (e.g., "Full House"). |
Sources: types/poker.ts:15-21
Supporting Types
The following diagram shows the relationship between HandEvaluation and its supporting types like Card, Rank, and HandRank.
This diagram illustrates the composition of a HandEvaluation object.
Sources: types/poker.ts:1-21
Hand Ranking and Value Calculation
To compare hands, each HandRank is assigned a base numerical value. A final, more precise value is calculated by adding a kicker value, which resolves ties between hands of the same rank.
Sources: lib/poker-engine.ts:25-38, 292-353
Hand Rank Values
The HAND_RANK_VALUES constant defines the base score for each hand type. Higher ranks have significantly larger values to ensure they always beat lower ranks.
| Hand Rank | Base Value |
|---|---|
high-card | 1 |
pair | 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 | 10 |
This value is multiplied by 1,000,000 to create space for kicker values.
Sources: lib/poker-engine.ts:25-38, 172-261
Kicker Value Calculation
When two players have the same hand rank (e.g., both have a Pair), a secondary value is calculated based on the ranks of the cards involved (the pair and the "kickers"). This ensures, for example, that a pair of Aces beats a pair of Kings.
getHighCardValue: Calculates value based on all 5 cards.getPairValue: Calculates value based on the pair's rank and the three kickers.getTwoPairValue: Calculates value based on the two pair ranks and the single kicker.getTripValue: Calculates value based on the three-of-a-kind rank and the two kickers.getFullHouseValue: Calculates value based on the three-of-a-kind rank and the pair rank.getQuadValue: Calculates value based on the four-of-a-kind rank and the single kicker.
Sources: lib/poker-engine.ts:321-382
Evaluation Flow
The evaluation process differs slightly between Texas Hold'em and Omaha due to their distinct rules for hand composition.
Texas Hold'em Evaluation (evaluateHand)
In Texas Hold'em, a player can use any combination of their 2 hole cards and the 5 community cards to make the best 5-card hand. The evaluateHand function iterates through all possible 5-card combinations to find the strongest one.
The following flowchart shows the logic of the evaluateHand function.
Sources: lib/poker-engine.ts:111-124
Omaha Evaluation (evaluateOmahaHand)
Omaha rules are stricter: a player must use exactly 2 of their 4 hole cards and exactly 3 of the 5 community cards. The evaluateOmahaHand function enforces this rule by generating combinations accordingly.
The following flowchart shows the logic of the evaluateOmahaHand function.
Sources: lib/poker-engine.ts:126-147
Core 5-Card Evaluation (evaluateFiveCards)
This is the central function that analyzes a single 5-card hand and returns a HandEvaluation. It checks for hands in descending order of strength.
The following flowchart details the logic inside evaluateFiveCards.
Sources: lib/poker-engine.ts:149-263
Integration into Game Logic
The hand evaluation functions are primarily used at the showdown phase of the game to determine the winner(s) of the pot.
Winner Determination (determineWinners)
The determineWinners function orchestrates the evaluation for all active (non-folded) players at the end of a hand.
The sequence diagram below illustrates the process.
This process is initiated from the advancePhase function when the game state moves to river or from the usePokerGame hook which orchestrates game flow.
Sources: lib/poker-engine.ts:401-432, hooks/use-poker-game.tsx:102-113
Testing
The hand evaluation logic is validated through a series of test cases defined in lib/hand-evaluation-test.ts. These tests cover all possible hand ranks to ensure the evaluateHand function provides correct results.
Example Test Cases
| Description | Cards | Expected Rank |
|---|---|---|
| Royal Flush in Hearts | A♥ K♥ Q♥ J♥ 10♥ | royal-flush |
| Straight Flush (9-high) | 9♦ 8♦ 7♦ 6♦ 5♦ | straight-flush |
| Four of a Kind (Aces) | A♥ A♦ A♣ A♠ K♥ | four-of-a-kind |
| Full House (Kings over 3s) | K♥ K♦ K♣ 3♠ 3♥ | full-house |
| Flush (Ace-high Spades) | A♠ 10♠ 7♠ 5♠ 2♠ | flush |
| Straight (Wheel: A-5) | A♥ 5♦ 4♣ 3♠ 2♥ | straight |
| Three of a Kind (Queens) | Q♥ Q♦ Q♣ 7♠ 2♥ | three-of-a-kind |
| Two Pair (Jacks and Sixes) | J♥ J♦ 6♣ 6♠ A♥ | two-pair |
| Pair (Tens) | 10♥ 10♦ K♣ 9♠ 3♥ | pair |
| High Card (Ace-high) | A♥ J♦ 9♣ 6♠ 2♥ | high-card |
The runHandEvaluationTests function iterates through these cases to confirm the accuracy of the evaluation logic. The file also includes a validateOmahaEvaluation function to specifically test the constraints of Omaha.
Sources: lib/hand-evaluation-test.ts:11-122, 125-151
The results of hand evaluation are also visible in the UI, such as in the StatsDashboard which displays the player's "Best Poker Hand".
Sources: components/stats-dashboard.tsx:210-227, components/rules-page.tsx:55-98