PokerML
From the PokerML wiki
PokerML is a simulation-driven heads-up and multiplayer no-limit hold'em engine that blends heuristic game-tree search with configurable card and action abstractions to explore poker strategy. The engine is designed for researchers and strategy experimenters who want to inspect and modify poker abstractions, search depth, bet sizing, and range handling rather than a production solver. It implements Counterfactual regret minimization for iterative strategy training, Game state management to track poker hand state, Interactive play and self-play for human and bot gameplay, and Solver optimization to accelerate subgame solving.
flowchart LR n1[["Counterfactual regret minimization"]] n2[["Game state management"]] n3[["Interactive play and self-play"]] n4[["Legacy card utilities"]] n5[["Solver optimization"]] n1 -->|"20 calls, 13 imports"| n2 n5 -->|"13 calls, 10 imports"| n1 n5 -->|"12 calls, 11 imports"| n2 n2 -->|"9 calls, 9 imports"| n1 n3 -->|"6 calls, 6 imports"| n2 n3 -->|"4 calls, 4 imports"| n1 n1 -->|"4 calls, 3 imports"| n3 n5 -->|"2 calls, 2 imports"| n3 n1 -->|"1 call, 1 import"| n5 n2 -->|"1 call, 1 import"| n3 n2 -->|"1 call, 1 import"| n4 n2 -->|"1 call, 1 import"| n5 n3 -->|"1 import"| n5
Purpose and features
Train poker strategies toward Nash equilibrium through Counterfactual regret minimization, which iteratively computes regrets for unchosen actions and updates play probabilities via regret matching.[1] (see Counterfactual regret minimization) Evaluate trained strategies by measuring their exploitability against a Local Best Response that tracks opponent ranges via Bayes' rule. (see Counterfactual regret minimization) Experiment with search depth, bet sizing, and range abstractions by modifying configurable parameters like BET_SIZINGS, SEARCH_MAX_DEPTH, and MONTE_CARLO_BASE without changing core solver logic.[2] Resolve subgames using a depth-limited solver that replaces the full game tree below a threshold with Solver optimization techniques including mutable game state, neural network leaf value estimation, and Numba-compiled regret matching. (see Solver optimization)
Play heads-up poker against a trained CFR bot in real-time through Interactive play and self-play, which includes human-versus-bot gameplay with live solver visualization and bot-versus-bot self-play sessions to detect strategy imbalances.[3] (see Interactive play and self-play)
Layers
- The Counterfactual regret minimization layer implements the core CFR training algorithm, information set tracking, and strategy storage. (see Counterfactual regret minimization)
- The Game state management layer models poker hand state as a
GameStateobject that tracks position, action history, folded/all-in status, and exposes methods to apply actions and compute legal moves. (see Game state management) - The Interactive play and self-play layer provides CLI entry points for human-versus-bot gameplay and bot-versus-bot duplicate-matched sessions with frequency tracking. (see Interactive play and self-play)
- The Solver optimization layer accelerates solving through mutable game state, neural network leaf value estimation, and Numba-compiled numerical routines. (see Solver optimization)
- The Legacy card utilities layer provides card representation conversion, poker hand generation, suit abstraction functions, and preflop equity lookup tables. (see Legacy card utilities)
Request paths
- Game state transitions in Game state management call
determine_winners()fromcfr/evaluator.pyto resolve hands at showdown and update pot calculations viaGameState._calculate_side_pots()incfr/game_state.py.[4] - Training a strategy in Counterfactual regret minimization flows from
train.pythroughCFRTrainer.train(), which constructsFastStateobjects and applies action abstractions to iterate the regret minimization loop.[5] - Playing a hand in Interactive play and self-play starts with
GameStatefrom Game state management, callsSubgameSolver.solve()from Solver optimization at decision points, and loads strategy to recommend actions.[6] - Self-play creates game states via Game state management, applies bot actions through a
Botinstance that loads strategy and callsSubgameSolver, and tracks frequencies to measure strategy balance.[7]
Feature dependencies
- Counterfactual regret minimization depends on Game state management for game state objects and action legality, importing
GameStateandget_position_namefromcfr/game_state.pyand using it throughout training.[8] - Counterfactual regret minimization depends on Solver optimization for mutable state representation, importing
FastStateand action encoding utilities fromcfr/fast_state.pyto serialize strategies during training.[9] - Counterfactual regret minimization depends on Interactive play and self-play for strategy persistence, calling
load_strategy()andsave_strategy()fromcfr/strategy_store.pyto resume training and store results.[10] - Solver optimization depends on Counterfactual regret minimization for blueprint strategy data and action abstractions, importing
InfoSet, card abstractions, and action utilities fromcfr/modules.[11][12] - Solver optimization depends on Game state management for game constants and action translation, importing
STARTING_STACK,SMALL_BLIND, and action-to-chip conversion fromcfr/game_state.py.[13][14] - Interactive play and self-play depends on Game state management for game state construction and action validation, importing
GameState,STARTING_STACK, andget_position_nameto manage live gameplay.[15] - Interactive play and self-play depends on Counterfactual regret minimization for strategy loading and exploitation evaluation, importing card abstractions and strategy utilities from
cfr/modules.[16][17] - Interactive play and self-play depends on Solver optimization for real-time subgame resolution, importing
SubgameSolverfromcfr/subgame_solver.pyto compute optimal plays during live games.[18] - Game state management depends on Counterfactual regret minimization for action legality and evaluation, calling
determine_winners()fromcfr/evaluator.pyto resolve showdowns.[19] - Game state management depends on Legacy card utilities for card number-to-text conversion, calling
CardUtils.numToCard()inserver/game_manager.pyto render cards to players.[20][21] - Game state management depends on Solver optimization for subgame solving, importing
SubgameSolverfromcfr/subgame_solver.pyinserver/bot.pyto resolve real-time decisions.[22] - Solver optimization and Interactive play and self-play both depend on trained strategy files stored via Counterfactual regret minimization, calling
load_strategy()to retrieve serialized blueprint strategies for solving and gameplay.[23][24]
References
-
^
README.md:L23-24@56ad610 -
^
README.md:L48-60@56ad610 -
^
README.md:L19@56ad610 -
^
cfr/game_state.py:L408-414@56ad610(GameState.get_terminal_utility) -
^
cfr/cfr_trainer.py:L19-30@56ad610 -
^
play.py:L13-17@56ad610 -
^
server/bot.py:L30-40@56ad610(Bot.__init__) -
^
cfr/cfr_trainer.py:L22@56ad610 -
^
cfr/cfr_trainer.py:L23-25@56ad610 -
^
cfr/cfr_trainer.py:L30@56ad610 -
^
cfr/depth_limited_solver.py:L17@56ad610 -
^
cfr/fast_state.py:L17-18@56ad610 -
^
cfr/depth_limited_solver.py:L18@56ad610 -
^
cfr/fast_state.py:L17-20@56ad610 -
^
play.py:L13@56ad610 -
^
play.py:L12@56ad610 -
^
play.py:L14-15@56ad610 -
^
play.py:L16@56ad610 -
^
cfr/game_state.py:L22@56ad610 -
^
server/game_manager.py:L15@56ad610 -
^
server/game_manager.py:L539@56ad610(_cards) -
^
server/bot.py:L23@56ad610 -
^
tests/test_benchmarks.py:L43@56ad610 -
^
play.py:L14@56ad610
This page was last edited on 24 March 2026, at commit 56ad610.