Poker Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Poker Engine is the core module responsible for managing the entire lifecycle of a poker hand. It is a stateless collection of functions that processes game state, player actions, and rule enforcement. The engine is designed to be independent of the user interface, receiving the current game state and a player action, and returning a new, updated game state. It supports multiple game modes, including standard Texas Hold'em (for SNG/MTT), Omaha, and a special "All-in or Fold" variant.
The primary interaction with the engine from the frontend is managed through the usePokerGame hook, which holds the GameState in React state and calls the engine's functions to process game logic. The engine handles card dealing, betting rounds, hand evaluation, and winner determination, making it the central authority for all poker rules within the application.
Sources: lib/poker-engine.ts, hooks/use-poker-game.tsx
Core Data Structures
The engine's logic revolves around a set of well-defined types that model the game's state. The most important of these is GameState, which provides a complete snapshot of the current hand.
Sources: types/poker.ts
Key Data Types
| Type | Description | File |
|---|---|---|
GameState | A comprehensive object containing all information about the current hand, including players, pot size, community cards, and current phase. | types/poker.ts:46-62 |
PlayerState | Represents the state of a single player, including their cards, chips, current bet, and status (e.g., folded, all-in). | types/poker.ts:34-42 |
Card | A simple interface representing a playing card with a suit and a rank. | types/poker.ts:4-7 |
PlayerAction | A type defining the possible actions a player can take: fold, check, call, raise, all-in. | types/poker.ts:32 |
GamePhase | A type for the distinct phases of a hand: waiting, pre-flop, flop, turn, river, showdown, complete. | types/poker.ts:33 |
GameMode | A type specifying the poker variant being played: sng, mtt, allin, omaha. | types/poker.ts:33 |
HandEvaluation | An object returned by the evaluation functions, containing the hand's rank, calculated value, and description. | types/poker.ts:18-23 |
Data Structure Relationship Diagram
This diagram illustrates the relationship between the main data structures used by the Poker Engine.
Sources: types/poker.ts:4-62
Game Lifecycle
The engine manages the game through a series of distinct phases, starting with initialization and progressing through betting rounds until a winner is determined.
1. Game Initialization
A new game is started using the initializeGame function. This function sets up the initial GameState for the first hand.
The initialization process is as follows:
- It accepts player IDs, names, seat numbers, starting chips, the dealer's seat, and the
GameMode. - The
deckManageris reset to provide a fresh, shuffled deck. - Cards are dealt to each player based on the
gameMode(4 for Omaha, 2 for others). PlayerStateobjects are created for each player.- Players are sorted by their
seatNumberto ensure correct turn order. - The dealer, small blind, and big blind positions are calculated based on the dealer's seat.
- An initial
GameStateobject is constructed and returned.
Sources: lib/poker-engine.ts:411-449, hooks/use-poker-game.tsx:39-60
This flowchart shows the game initialization sequence.
2. Processing Player Actions
Player actions are the primary driver of the game's progression. The processAction function is the entry point for all moves.
When a player acts, the usePokerGame hook calls processAction with the current GameState, the player's ID, the action, and an optional amount.
The function performs the following steps:
- Validates that the acting player is valid (not folded, not all-in).
- For
allingame mode, it rejects any action other thanfoldorall-in. - Executes the action (
fold,check,call,raise,all-in), updating the player's state (chips,bet,folded,allIn) and the game state (pot,currentBet). - Calls
advanceTurnto determine the next state of the game.
Sources: lib/poker-engine.ts:550-642, hooks/use-poker-game.tsx:95-111
This sequence diagram shows a typical player action flow.
3. Advancing Turns and Phases
The game progresses through turns and phases automatically after each action.
advanceTurn(gameState): After an action, this function checks if the betting round is over.- If all active players have acted and their bets match the
currentBet, it callsadvancePhase. - Otherwise, it finds the next player who is not folded or all-in and updates
currentPlayerIndex.
- If all active players have acted and their bets match the
advancePhase(gameState): This function transitions the game to the next phase. It functions as a state machine.
Sources: lib/poker-engine.ts:644-711
This state diagram visualizes the game phase transitions managed by advancePhase.
Sources: lib/poker-engine.ts:662-711, types/poker.ts:33
4. Starting a New Hand
Once a hand is complete, the usePokerGame hook calls startNewHand to begin the next one. This function:
- Resets the deck using
deckManager.reset(). - Resets each player's
bet,cards,folded, andallInstatus. - Rotates the dealer button to the next active player.
- Calculates the new blind positions.
- Deals new cards according to the
gameMode. - Posts the small and big blinds from the appropriate players.
- Sets the
currentPlayerIndexto the player after the big blind. - Returns the new
GameStatefor thepre-flopphase of the new hand.
Sources: lib/poker-engine.ts:452-518, hooks/use-poker-game.tsx:128-137
Hand Evaluation and Winner Determination
A critical responsibility of the Poker Engine is to evaluate hands and determine the winner(s) at showdown.
Hand Ranks
The engine defines a clear hierarchy of hand ranks, each with a numerical base value.
| Hand Rank | Base Value | File |
|---|---|---|
royal-flush | 10 | lib/poker-engine.ts:38 |
straight-flush | 9 | lib/poker-engine.ts:37 |
four-of-a-kind | 8 | lib/poker-engine.ts:36 |
full-house | 7 | lib/poker-engine.ts:35 |
flush | 6 | lib/poker-engine.ts:34 |
straight | 5 | lib/poker-engine.ts:33 |
three-of-a-kind | 4 | lib/poker-engine.ts:32 |
two-pair | 3 | lib/poker-engine.ts:31 |
pair | 2 | lib/poker-engine.ts:30 |
high-card | 1 | lib/poker-engine.ts:29 |
Sources: lib/poker-engine.ts:28-39, components/rules-page.tsx:47-92
Evaluation Logic
The engine provides two main evaluation functions:
evaluateHand(cards): For Texas Hold'em. It takes an array of 7 cards (2 hole + 5 community) and finds the best possible 5-card combination.evaluateOmahaHand(holeCards, communityCards): For Omaha. It iterates through all combinations of exactly 2 hole cards and 3 community cards to find the best 5-card hand.
Both functions rely on evaluateFiveCards, which checks for flushes, straights, and card rank counts to identify the hand and calculate a precise value. This value incorporates the hand rank and the ranks of the relevant cards (and kickers) to allow for direct comparison between two hands.
Sources: lib/poker-engine.ts:114-152, lib/poker-engine.ts:154-263, lib/hand-evaluation-test.ts
Determining Winners
The determineWinners function is called during the showdown phase.
- It filters for players who have not folded.
- If only one player remains, they are the winner by default.
- Otherwise, it calls the appropriate evaluation function (
evaluateHandorevaluateOmahaHand) for each active player. - It compares the
valueof each player's best hand. - It returns an array of player IDs who have the highest hand value. This array can contain multiple IDs in the case of a tie.
Sources: lib/poker-engine.ts:388-409
This flowchart outlines the winner determination logic.
Sources: lib/poker-engine.ts:388-409