Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mako

Heads-up no-limit Texas Hold'em in your terminal, against an AI trained with counterfactual regret minimization.

== hand #3 — Mako post(s) the small blind ==
   Mako raises to 6.

   board: (preflop)          pot: 8
   you [Ah Kd] stack 38  |  Mako [?? ??] stack 34  |  4 to call
   [f] fold   [c] call 4   [h] half-pot -> 12   [p] pot -> 18   [a] all-in -> 40
   you>

Sessions run at 20, 50, or 100 BB (1/2 blinds, stacks reset every hand) with six discrete actions: fold, check, call, half-pot, pot, all-in. Rules are specified exactly in docs/RULES.md.

Build and play

Requires CMake ≥ 3.20 and a C++20 compiler. No third-party C++ deps.

cmake -S . -B build
cmake --build build -j
./build/mako                     # asks for a depth, loads the matching artifact
./build/mako --depth 100         # or pick one directly

Type help at any prompt. Between hands, analysis reviews the last hand with true equities and Mako's strategy mix at every decision; stats shows your session plus lifetime numbers (persisted at ~/.mako/stats.json). Full reference: docs/CLI.md.

How the bot works

  1. Rules engine (C++, cpp/game/) — integer-chip heads-up NLHE with the six-action grid; the single source of truth for both training and play, covered by golden scripted-hand tests.
  2. Abstraction (cpp/abstraction/, docs/ABSTRACTION.md) — 169 preflop classes; postflop, suit-canonicalized equity-vs-random buckets, finer at deeper stacks (up to 32/48/64). Implemented twice (C++ and pure Python python/mako_ref/) with bit-parity tests.
  3. Trainer (cpp/trainer/ + python/mako_trainer/) — external-sampling linear MCCFR. The C++ core trains at thousands of iterations per second; the pure-Python twin is the readable reference, and the two are tested to produce bit-identical tables and byte-identical artifacts. Deterministic per seed, checkpoint/resume, TOML configs in configs/, and a persistent canonical-equity cache shared by every run at every depth.
  4. Artifact (docs/STRATEGY_FORMAT.md) — the average strategy exported as a versioned binary; game and abstraction parameters travel inside it. Shipped: mako-20bb-v2.mako (3M iterations, 184k info sets), mako-50bb-v2.mako (4M, 1.1M), and mako-100bb-v2.mako (5M, 2.9M).
  5. Inference (C++, cpp/infer/) — loads the artifact, binary-searches the info-set hash, samples from the stored mix with a seeded RNG. Unseen spots (0.00% measured vs random play) use a counted, passive check/call fallback.

Training your own

uv sync
cmake -S . -B build -DMAKO_BUILD_PYTHON=ON \
    -DPython_EXECUTABLE=$PWD/.venv/bin/python \
    -Dpybind11_DIR=$(.venv/bin/python -m pybind11 --cmakedir)
cmake --build build -j

uv run mako-train --config configs/smoke.toml                   # <1 min pipeline check
uv run mako-train --config configs/v2-20bb.toml --prewarm turn  # ~35 min from cold
uv run mako-train --config configs/v2-50bb.toml                 # reuses the equity cache
uv run mako-train --config configs/v2-100bb.toml

--prewarm turn precomputes every canonical flop/turn equity across all cores once; the result lands in strategies/equity.cache and every later run — any depth — starts warm (bucket equity depends on cards, never stack). Interrupting a run checkpoints it; resume with --resume <out>.ckpt. Other depths/bucket counts: copy a config and edit — the artifact carries its parameters, so play just works. Gate a candidate before shipping it:

uv run mako-eval strategies/mako-20bb-v2.mako --vs strategies/mako-20bb-v1.mako

Browser (WASM)

The same engine and artifact run fully in-browser via an Embind façade (cpp/wasm/): MakoSession wraps strategy loading, the hand loop, and post-hand analysis behind a JSON snapshot API, so a web worker stays a thin message router. Requires emsdk (or brew install emscripten):

emcmake cmake -S . -B build-wasm -DMAKO_BUILD_WASM=ON -DMAKO_BUILD_TESTS=OFF
cmake --build build-wasm -j       # emits build-wasm/mako.js + mako.wasm

node cpp/wasm/smoke.mjs           # plays one full hand + analysis in Node

Ship mako.js, mako.wasm, and a .mako artifact together; the consumer fetches the artifact and passes its bytes to MakoSession.loadStrategy.

Tools: mako-inspect (artifact metadata, per-key mixes, preflop open table), mako-selfplay (mirror or vs-baseline EV), mako-equity (hand equity queries), mako-eval (ship gates with confidence intervals).

Strength, measured — and limitations

Every shipped artifact must pass mako-eval (1M-hand matches, 95% CIs): mirror self-play ≈ 0, clearly +EV vs a passive check/call baseline, and a near-zero unseen-spot rate. Measured at ship time:

Artifact Info sets Mirror EV vs check/call Button edge Missing keys
20 BB v2 183,646 +0.1 ±1.3 +129 BB/100 +3.7 0 in 8.3M
50 BB v2 1,124,499 −0.9 ±2.1 +204 BB/100 +13.3 0 in 9.3M
100 BB v2 2,854,097 −1.9 ±2.8 +229 BB/100 +14.6 1 in 9.4M

The 20 BB v2 strategy also beats the retired v1 head-to-head by +12.6 ±1.4 BB/100. (The growing button edge with depth is the expected positional effect, not an artifact.)

Honesty about what this is: an approximate equilibrium of a deliberately coarse abstract game — equity-vs-uniform buckets with no range conditioning or potential-aware clustering, and six fixed bet sizes. Do not call it GTO. Deeper stacks amplify abstraction error, which is why the grids are finer there; a strong human hunting abstraction seams will still find them, most easily at 100 BB. See the Honesty section of docs/ABSTRACTION.md.

Tests

./build/mako_tests    # engine, evaluator, abstraction, inference, trainer, stats
uv run pytest         # trainer parity, exporter, tools, C++/Python parity

Layout

cpp/game/         rules engine          docs/RULES.md
cpp/eval/         hand evaluator
cpp/abstraction/  info-set keys         docs/ABSTRACTION.md
cpp/trainer/      fast MCCFR core
cpp/infer/        strategy loading      docs/STRATEGY_FORMAT.md
cpp/cli/          mako TTY + harness    docs/CLI.md
cpp/bindings/     pybind11 module
cpp/wasm/         Embind browser façade
python/mako_trainer/  MCCFR reference + export
python/mako_ref/      pure-Python parity reference
python/mako_tools/    inspect / selfplay / equity / eval
strategies/           shipped artifacts

About

Gamble Gamble

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages