PokerAlpha
An open research and engineering project for game-theoretic decision-making under hidden information.
A custom Hold’em engine, CFR/MCCFR solvers, a bit-exact C++ training backend, exact reduced-game validation and a calibrated abstention layer. The question behind it: how do imperfect-information systems behave when their abstractions are wrong, their policies disagree, and compute is limited?
The answer is a distribution, and nobody tells you whether it is right
In poker you never see the other player’s cards, so good play is randomized and has to be learned rather than looked up. Heads-up no-limit Hold’em has around 10160 states, so any strategy is trained on a simplified abstraction of the game, and that simplification has an error of its own. PokerAlpha handles this in three steps.
Counterfactual regret minimization plays the game against itself and shifts weight toward actions it regrets not taking. 3 independent runs of 2,000,000 iterations each: one is the release strategy, and the disagreement between them is measured.
Small games (Kuhn, Leduc, single-street river subgames) can be solved exactly, so the solver and the abstraction are measured there instead of being assumed correct.
A calibrated confidence gate looks at training visits and disagreement between runs, and shows no numbers at all for states it cannot trust.
Three demos that run in your browser
Nothing to install. The first two compute live on your machine.

Watch a solver learn
Run counterfactual regret minimization on Kuhn poker and watch exploitability fall as the strategy improves.
Real CFR computation, checked against the Python reference. Not an animation.
Run the solver →
Play the Arena
Play heads-up Kuhn poker against the trained CFR policy, then see the exact exploitability of how you played.
A small-game sandbox. It does not use the Hold'em release strategy.
Play a hand →
Explore Phase II results
Abstraction refinement, the native speedup, a resolving time-budget slider, translation costs and the ideas that failed.
Precomputed exact results from reduced games, with their controls.
Open the results →Five results, with their limits
Each comes with a matched control and a confirmation run. Most are exact measurements in small or single-street games, which is where exact answers exist; none is a full-Hold’em theorem.
Error-guided abstraction refinement
Splitting the bucket with the largest measured error lowered exploitability 24% below a uniform refinement with identical capacity on independent confirmation (31% in both the discovery and double-capacity runs).
MethodExact 52-card river subgames, vectorized CFR+, capacity-matched uniform and random controls, 45 confirmation instances on new seeds and boards.
LimitSingle-street, perfect-recall domain. No Hold'em abstraction was retrained from it.
Profile-driven native optimization
A further 1.96× training throughput over the first native port, with an identical strategy digest.
MethodSampling profile, then A/B builds with identical Release flags run in alternating processes; parity suite and sanitizer self-test re-run.
LimitTraining throughput only. End-user analysis latency is a separate measurement.
Off-tree bet translation
With a release-like 33/75/150% menu, randomized pseudo-harmonic mapping cost 0.076 chips per hand against 0.601 for nearest-in-log-space, about 8× less. In a separate run, safe re-solving after the off-tree bet lowered pseudo-harmonic's cost from 0.061 to 0.048.
MethodExact best response in river subgames where the opponent may bet off-menu; 27 instances, repeated on independent seeds.
LimitReduced single-street subgames. The release still uses its nearest-in-log-space matcher; this is a recommendation, not a shipped change.
Decision-time resolving
Re-solving a subtree with a safe gadget closed 9% to 31% of a coarse blueprint's gap to equilibrium at a 1 s budget, and from 1 s up it was never worse than the blueprint by more than 1e-4 chips. Unsafe resolving was worse than the blueprint in most instances.
MethodRe-solve gadget with best-response counterfactual values (Burch et al. 2014), exact evaluation, budgets from 10 ms to 5 s.
LimitExact single-street subgames with a research blueprint. "Safe" is measured there, not guaranteed for full Hold'em; the release does not resolve.
Calibrated abstention
Confidence v2 accepts 1.68× as many decisions as v1 at a similar accepted wrong-action rate (3.0% vs 3.3%).
Method8,880 information states with exact EV-regret targets from nine solved games, evaluated leave-one-game-out. An ablation showed which signals carry it.
LimitCalibrated on small exact games; transfer to full Hold'em is an assumption, which is why flop and turn stay capped.
Charts and controls for these results → · the null and negative results are on the same page.
From 21.9 to 1,625 iterations per second
Warm MCCFR training throughput on the release configuration. The two benchmark endpoints and the first port come from the same benchmark script; the three optimization steps are an A/B experiment between native builds, reported as cumulative speedups.
- Python reference21.9 it/sExternal-sampling MCCFR in NumPy. Correct, and still the reference everything else is checked against, but a 2M-iteration run would take more than a day.
- Move the whole hot path to C++17837 it/s · 38.11×Rules, dealing, evaluator, infoset encoder, regret matching, sampling and the recursion itself. Moving only helper functions was tried first and lost its gains to per-node boundary crossings.
- Profile the native trainer69.5% of CPU in one functionmacOS sample on a symbolized -O3 build. Almost every new river board rebuilt a 1,081-hand percentile table, and external sampling rarely sees the same board twice.
- Deduplicate river percentile construction1.60× (A/B)A hand's 7-card value depends only on canonical card ids (exact card for the one flush-capable suit, rank otherwise). Evaluate each distinct pair once and keep cumulative counts instead of sorting.
- Reuse evaluator board counts1.70× cumulativeRank and suit histograms for the five board cards are built once per table; each holding adds two cards.
- Flat open-addressing infoset index1.96× cumulativeLinear probing with a splitmix64 hash replaces std::unordered_map on the per-node lookup.
- Fresh end-to-end benchmark1,625 it/s · 74.2×Same script and protocol as the original benchmark: three trials in fresh processes, warm median.
Scope
Everything below is implemented in this repository. Off-the-shelf pieces are the foundations: NumPy, pybind11, FastAPI, Next.js, Electron and pytest.
apps/webapps/desktoppoker_alpha/apipoker_alpha/observerpoker_alpha/decisionpoker_alpha/decision/solver_gate.pypoker_alpha/solverspoker_alpha/abstractionexperimentspoker_alpha/holdemcpp/srcpoker_alpha/pokerpoker_alpha/gamespoker_alpha/researchOne real decision through the pipeline
A♥K♦ on Q♠7♦2♣T♥3♥ · pot 5bb · checked to the hero on the river
modelled range after three passive streets: 7.64 bits, about 200 effective combos (a belief, not their cards)
gate verdict ACCEPTED, 226 training visits, low cross-seed disagreement
check 83% · bet_33 9% · bet_150 5%
Precomputed engine output, stamped with the generating commit. Walk through the whole hand.
What the system does not know
The interesting part is not pretending uncertainty disappears. PokerAlpha measures where trust breaks down, and refuses to answer there.
The release strategy is an abstract MCCFR average, not an equilibrium. A restricted local best response still finds at least ~100 bb/100 of exploitability.
The encoder is imperfect-recall, which voids CFR's convergence guarantee. In exact Leduc tests, one forgetful abstraction got worse with more training.
Exact flop and turn subgames show the encoder merging strategically different hands, so those streets are permanently capped at low confidence.
Seeds disagree on many preflop spots and on jam / 3-bet defense. Doubling training twice removed only about a tenth of the disagreement each time, so the gate rejects there.
The screen observer has limited real PokerNow tuning but has not yet been independently validated on a held-out real-world dataset. It is excluded from the product.
Nothing here is evidence of real-money win rate. The project never automates actions on a poker client.
Source now, desktop builds later
The full source, experiments and result files are on GitHub. Desktop builds for macOS, Windows and Linux are planned; until signed releases exist, the app runs from source.
Interested in quantitative research, high-performance systems, machine learning, and game-theoretic systems.