Poker TUI
A terminal gym for no-limit hold'em: drill preflop decisions against GTO-style
charts, then play 6-max cash games (100bb) against agents powered by the local
pi coding-agent CLI. Built with Textual and
managed with uv. Requires Python 3.11 or newer.
Quick start
uvx poker-tui
uvx downloads the published package into an isolated, cached environment and
starts the TUI without a manual install. For a persistent command:
uv tool install poker-tui
poker-tui
Check the installed release with poker-tui --version.
Screens:
- Preflop Trainer — random spots (RFI + facing opens across all positions),
where you choose one action or submit a complete mixed strategy, graded
against built-in charts with frequencies.
Reveals a 13x13 range grid after each decision, tracks accuracy by seat, and
"Why?" explanations in three styles (newb / learner / expert) generated
via
piand cached locally. Range charts and explanations can be opened full-screen; expanded range cells show the complete action mix in hover tooltips. - GTO Solver — enter exact hole cards and choose an unopened or facing-open situation to inspect the locally stored strategy from the experimental heads-up CFR+ abstraction, including action frequencies and sizes. Solver results never fall back to the authored trainer charts.
- Play vs Agents — six-handed NLHE, unitless BB, auto-rebuy. Five villain
seats decide via
pi(one-shot LLM calls) with a fast heuristic bot as fallback. Dedicated seat chips keep each blind post and latest street action visible. Once you're out of a hand the rest plays out at high speed;Njumps to the next deal. - Stats — quiz accuracy by spot and table results.
- Agent Settings — choose from models discovered through Pi for the default,
trainer coach, and each of the five villains, or enter any custom
provider/modelID. You can also switch to heuristic-only play.
Keys: T trainer · V solver · P play · S stats · G settings · Q quit · inside screens N next,
Esc back. Trainer actions use F/C/R; table actions use F to fold,
C to check or call, and R to raise at the selected size. S changes table
speed. In the trainer, G expands the revealed range and X expands a loaded
explanation; M switches between fixed-action and mixed-strategy answers.
Mixed strategies are scored by distribution overlap:
score = sum(min(your frequency, baseline frequency)), equivalently one minus
the total-variation distance. Against a 70% raise / 30% call baseline, an exact
70/30 submission scores 100%; pure raise scores 70%; pure call scores 30%.
Agents
Villain brains come from the pi CLI in
print mode (pi -p --no-tools --no-session ...). Each seat gets one of four
personas; invalid/failed LLM replies fall back to the heuristic bot
(chart-based preflop, Monte-Carlo-equity postflop) automatically.
Environment:
| Variable | Effect |
|---|---|
POKER_GYM_BOTS=heuristic |
skip LLM entirely (fast, free, offline) |
POKER_GYM_PI_ARGS="--model anthropic/..." |
pick model/provider for pi |
The settings screen loads Pi's local model catalog and persists choices in
settings.json. Per-agent models can inherit the default, while leaving the
default unset uses Pi's own configured default. Environment variables override
saved settings, which is useful for one-off runs and automation.
The solver
poker_gym.solve implements CFR+ over heads-up preflop subgames on top of a
169×169 all-in equity matrix (poker_gym.equity) computed by a custom
vectorized numpy 7-card evaluator that is fuzz-tested against treys.
uvx --from poker-tui poker-gym-solve --quality fast --jobs 4
uvx --from poker-tui poker-gym-stats
Quality tiers: fast (~2k trials/matchup), standard (4k), thorough (8k).
Builds are chunked with deterministic seeds and checkpointed, so they can be
interrupted and resumed, and parallelized with --jobs. On a Raspberry Pi,
prefer --quality fast --jobs 4; the evaluator is int32/vectorized to keep the
working set cache-friendly.
After the build completes, open GTO Solver from the main menu. Choose the
preflop situation, enter two cards in compact notation such as As Qs, and the
view shows the normalized fold/call/raise mix plus the solver's action size.
The view reads only local kind='solver' data and does not call or scrape an
external solver service.
Unopened-pot trees begin with the posted 0.5 BB small blind and 1 BB big blind.
They include a legal limp to 1 BB, followed by the big blind's check or fixed
4 BB isolation branch. Call amounts for blind defenders subtract chips already
posted. Re-run poker-gym-solve after upgrading if the view reports that older
charts need rebuilding; the cached equity matrix can be reused.
Honest caveat: the solver's game abstraction folds everyone but two
players and models postflop with constant-sum, relative equity-realization
factors. Calibration shows
this cannot reproduce position-dependent open frequencies (UTG and BTN become
literally the same game), so the trainer grades against hand-calibrated
charts modeled on published solver baselines; solver output is stored
separately as an experimental "solver view" (kind='solver' in the charts
table).
Data
Everything persists under $XDG_DATA_HOME/poker_gym (default
~/.local/share/poker_gym): gym.db (quiz attempts, hand histories,
explanation cache, charts), settings.json (Pi model routing), and equity.npz.
Development
uv sync
uv run poker-tui
uv run pytest -m "not slow" # full suite minus long equity-matrix test
uv run pytest -m slow # equity matrix sanity (builds a small matrix)
uv run python scripts/smoke_app.py # headless TUI smoke test
Build the same artifacts uploaded to PyPI with:
uv build --clear
uv publish
Layout: src/poker_gym/ — cards, ranges (chart DSL), charts (the
ranges themselves — edit freely, they're plain strings), spots (trainer),
engine (table state machine), agents, explain, equity, solve,
db, cli, app.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file poker_tui-0.3.1.tar.gz.
File metadata
- Download URL: poker_tui-0.3.1.tar.gz
- Upload date:
- Size: 55.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1eb15568b04dd010110f4b2ed41d2389d4cc0ffdabacb18a30c25420bda323f6
|
|
| MD5 |
796dad140569fb56dda6ef54a9d9baf4
|
|
| BLAKE2b-256 |
6c256536a17173c6a6ab6c09331c98c43b45fe16e417e658bc177b7e5eb9cb5c
|
File details
Details for the file poker_tui-0.3.1-py3-none-any.whl.
File metadata
- Download URL: poker_tui-0.3.1-py3-none-any.whl
- Upload date:
- Size: 61.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b81f6e416c206f57c46818ef65b0c121150888e6bf580a32fb896a607c34c38
|
|
| MD5 |
cc7bbafcf05283d029591bf3c513d765
|
|
| BLAKE2b-256 |
d570cdb7f8c4229e2bbf1840b63ba35630790574714d98a5b5686fd530278bdc
|