Skip to content

CFR for 6-max Hold'em: the poker AI this catalog has not built yet

Almost every post in this folder describes something that exists. You can open the file it talks about. This one is different on purpose: it describes a piece of AI that nobody in this project has written. There is no trained poker solver in the repository, no learned blueprint strategy, no 6-max opponent built on counterfactual regret minimization (CFR). The poker opponents that ship today are hand-tuned heuristics, and you can read every one of them in the relevant AI module.

So why write a whole post about code that is not there?

Because deciding what not to build yet -- and writing the direction down with its open questions attached -- is a real part of how this project works, and it is a skill worth stealing if you are learning to build software with an AI assistant. A lot of that work is not typing. It is deciding what the next thing is, recognising the right answer, and then being honest about why you have not paid for it. "Here is the correct approach, here is roughly what it would cost, and here is why the heuristic we shipped is good enough for now" is a more useful artifact than either a finished feature or a vague someday. This post is the long version of a pencil mark that already exists in the Texas Hold'em design doc: CFR is the right poker AI, and it is not built.

Why poker is the one game in the catalog that wants CFR

This project keeps a rule at the top of its design-reference doc, and it is load-bearing enough that every AI ticket is supposed to start there: the hidden-information AI algorithm is chosen by the structure of the game, not by whichever algorithm the author already knows. The worked version of that rule lives in the "Choosing the right hidden-information AI algorithm" section of DESIGN_RESOURCES.md, and it splits the catalog's hidden-information games into different algorithmic homes.

Most of them -- Bluff, Rail Routes -- are turn-based games where the hidden thing is opponent state: the cards in someone's hand, the dice under a cup, a secret destination ticket. Players alternate. That shape is the home territory of Information Set Monte Carlo Tree Search (ISMCTS), which searches over the family of states consistent with what the AI actually knows rather than over one fully-known state it cannot see.

Poker is not that shape, and the doc is blunt about the consequence. No-Limit Hold'em is multi-round betting under imperfect information with a continuous action space -- every decision is a bet/check/fold choice, and "bet" is not one move but a slider over chip amounts, repeated across pre-flop, flop, turn, and river. CFR is regret minimization over abstracted betting sequences, and it handles that structure far better than tree search does. The misuse warning in DESIGN_RESOURCES.md is explicit in both directions: do not substitute ISMCTS for CFR on poker, because "the game tree structure is different enough that ISMCTS is the wrong tool," and do not apply ISMCTS to poker-shaped simultaneous betting where it is "functionally inferior to CFR."

That warning matters more than it looks, and it generalises past games. A bad opponent that plays obviously random moves gets caught in the first playtest. A bad opponent that runs a respected algorithm on the wrong game shape produces moves with the shape of competence and the substance of nonsense -- and nobody notices, because the algorithm has a famous name behind it. The same failure mode shows up when you ask an AI assistant to design a system: it reaches for the technique it has seen most often. The defence is the same in both cases. Name the structure of the problem first; let the structure pick the tool.

For poker, the structure has already picked. The Hold'em design doc puts it plainly: poker is the imperfect-information game -- there is no perfect-information baseline to fall back to -- and the science is settled. The doc points at the published precedent without me having to invent any of it: Libratus and DeepStack (2017) for heads-up no-limit, and Pluribus (2019) for 6-max, all in the CFR family. As the doc says: the science is settled; implementation effort is the gating cost.

What a LAN-scale project can actually afford

Knowing CFR is the right family is the easy half. The half that takes judgment is which CFR -- because a research lab and a kitchen-table app give different answers, and the difference is entirely about what you can afford.

The design doc lays out a ladder, and each rung trades cost for strength:

  • Heuristic charts. Starting-hand rules of thumb, fixed bet sizing, no opponent modelling. This is what ships today. Days of work; beats absolute beginners.
  • CFR blueprint with simplified abstractions. A small CFR solve with coarse buckets, or a pre-flop chart plus a post-flop heuristic. Beats casual players consistently. Existing open-source implementations exist to build on.
  • Deep-CFR or full-resolution CFR with action abstraction. Beats most humans. Weeks of training and careful abstraction work.
  • Real-time solving on inference (DeepStack-style), which actually solves a sub-tree per decision. Approaches superhuman; the most engineering of the lot.

The two words doing the work in the middle rungs are abstraction and buckets, and they are worth a sentence for a newcomer. The real game has far too many distinct situations to solve exactly -- every possible hand against every possible board against every possible bet size is an astronomically large tree. CFR does not solve that tree directly. You first abstract it: group similar hands into a manageable number of buckets, and discretise the continuous bet slider into a handful of sizes. The bucket count is the dial. Coarse buckets are cheap to train and play bluntly; fine buckets play far better and cost far more. Almost all of the "how strong, how expensive" question is really "how fine are the buckets."

The cost numbers, again straight from the design doc rather than invented here: days to weeks of CFR training to reach strong-amateur level, weeks to months to approach the published research bots. The trained "blueprint" is a lookup table, GB-scale uncompressed, distillable down to bundle-friendly sizes in the tens-to-hundreds of megabytes; and once trained, inference is just a strategy lookup -- fast, no GPU at runtime. There is also a build-versus-buy choice the doc flags as an open question: OpenSpiel ships CFR implementations, and building on one of them cuts months off the training-pipeline work versus writing the solver from scratch.

Put the ladder and the dial together and the affordable answer for a hobby-scale LAN project almost writes itself. You do not want the lab's answer. Full-resolution real-time solving is the right tool for beating professionals and the wrong tool for a friend-group poker night, the same way "play perfect GTO" is the wrong product goal even when it is technically the strongest one. The doc says it directly: do not make the AI play GTO blindly, because a "perfect" AI is boring; aim for strong amateur and leave headroom. So the realistic next step is a coarse blueprint on top of an existing OSS CFR implementation, sized to "consistently beats a casual player," not a from-scratch solver chasing a research benchmark. The correct algorithm family is settled; the only real engineering decision is which rung buys enough quality for this audience at a price a hobby project can pay.

A solved baseline the personalities would be tuned against

Here is the part that surprises people: even if a CFR blueprint existed tomorrow, it would not be the opponent you actually sit down against.

That is the same stance this project already takes for its other games, argued at length in AI opponents that play like people, not optimizers: the opponent you want is a person, not an optimizer. The poker design doc echoes it -- a perfect AI is boring; exploitable tendencies are what make an opponent feel like a character. The poker opponents that ship today lean all the way into that. TAG, LAG, Nit, Calling Station, and Maniac, all real classes in the relevant AI module, are each a small dictionary of knobs -- entry_threshold, call_threshold, raise_threshold, aggression, bluff_rate, size_pressure -- read by one shared heuristic that estimates hand strength and picks an action. The Maniac bluffs most of the time because its bluff_rate is set high, not because a model decided to. These are deliberate, legible policies. They are not a solver, and they are not pretending to be.

What they are missing is a reference point. In the MCTS lineup from the personalities post, Steady Eddie is the calibration baseline: the opponent who just plays the solid move when there is one, so that every other personality can be defined as a deliberate deviation from him. Poker has no Steady Eddie yet -- the heuristics are tuned by feel against each other, with no near-equilibrium zero-point to measure against. A CFR blueprint is the natural candidate to be that zero-point. The design doc already frames the personalities as "parameter mixings on a trained CFR strategy" -- bet-frequency multipliers, bluff-frequency tuning, calling-threshold adjustments. Read that the right way and a future blueprint does not replace the cast; it becomes the equilibrium the cast deviates from on purpose.

That is also what would make the teaching honest. The design doc's "personalities as teachers" idea is that each archetype is a lesson: you play a calling station to learn how to value-bet, a maniac to learn how to call down lighter, a nit to learn how to read a tight range. Today those lessons rest on the designer's intuition about what each personality exaggerates. With an equilibrium baseline to measure against, you could say exactly how far a personality deviates from the solved line and therefore exactly which skill the deviation trains. Same "personalities, not optimizers" philosophy as the rest of the catalog -- but now with a measuring stick instead of a vibe.

A direction, not a finished thing

To be unambiguous, because the whole point of this post is honesty about state: none of the above is implemented. There is no trained blueprint, no 6-max CFR opponent, no solver of any rung in the repository. The opponents are the heuristics in the relevant AI module, and that is the whole poker AI that exists right now.

What is written down is the direction, plus the questions a future ticket will have to answer first. The design doc names them and I will not pretend to settle them here:

  • Heads-up first, or straight to 6-max? Heads-up is fully solved and cheap to ship as a proof point; 6-max matches how people actually play (and is the friend-group sweet spot this post is named for) but is harder. The doc leans toward heads-up as the first rung, then 6-max.
  • Build on OSS or from scratch? OpenSpiel's CFR implementations are the lean path; the from-scratch route buys control at the cost of months.
  • How does the blueprint ship? Bundled with the app (large), served from the backend, or eventually compiled to run in the browser. The doc leans server-side to start.

None of those have committed answers, and that is fine -- naming them is the deliverable. This is the transferable lesson for anyone learning to build this way: a healthy backlog is full of entries exactly like this one. Known-right, not-yet-paid-for, with the structural question already decided and the open questions written down so the eventual implementation ticket starts from a real decision instead of a blank page. Writing the direction down is cheap. Discovering, after a week of training, that you reached for the wrong algorithm because nobody asked about the game's structure first is not.

So the heuristics stay, and they are genuinely good enough -- good enough to teach a newcomer pot odds at the table tonight. CFR is the rung above them: on the shelf, labelled, waiting for the day the audience and the budget make a days-to-weeks training run worth it. Until that day, this post is the pencil mark. And the pencil mark, drawn honestly, is the point.