Texas Hold’em Gym is a desktop playground for no-limit Texas Hold’em: a live table with bots, range/strategy setup, preflop solver + Monte Carlo equity tools, preflop and flop training drills, and bankroll / stats tracking. The UI is Qt 6 (QML / Qt Quick); game logic, evaluation, and tests are C++17.
- Lobby & table — configurable blinds and stacks; human vs bots; sit-out; timed decisions; pot + call indicator; Min / ⅓ / ½ / ⅔ / Pot / All bet-sizing presets.
- Bots & ranges — per-seat bot style and editable opening ranges (matrix / text); per-seat buy-in capped at 100× big blind, with excess bankroll off the table (see Game in code).
- Solver & equity — Monte Carlo equity vs a range or exact villain cards, with optional pot-odds and chip-EV (work is off the UI thread where applicable); toy Nash (Kuhn-style) solver for study.
- Training — Preflop through river drills with strategy-based grading, progress stats (accuracy, EV loss in bb), and configurable auto-advance delay.
- Bankroll & stats — seat stacks, off-table bankroll, leaderboard, and bankroll-over-time chart after each completed hand.
- Hand history — browse completed hands and actions from the embedded SQLite log (Setup also offers a factory reset that clears this data).
- Core engine — full hand from deal through showdown: blinds, streets, betting order, hand evaluation (best five of seven), side-pot–aware payouts. Details: Game in code.
| Path | Role |
|---|---|
CMakeLists.txt |
Top-level CMake: Qt 6, C++17, optional tests |
build.sh |
Optional script: clean configure, Ninja build, ctest, then runs the app |
poker/main.cpp |
QGuiApplication, QML engine; exposes pokerGame, pokerSolver, toyNashSolver, sessionStore, trainingStore, trainer, handHistory (read-only hand log), and bundled appFontFamily* strings |
poker/qml/ |
QML UI; assets and application.qrc |
poker/poker/ |
Cards, player, game + game_ui_sync, hand eval, bots, ranges, equity, solver, toy Nash, training store/controller, session store; Boost.Test smoke tests (optional) |
You need a toolchain, CMake, Qt 6.10+ (Quick stack), and Boost (headers + unit_test_framework) only if you build tests (BUILD_TESTING ON, default). See Building for versions, optional tools, distro packages, environment variables, and troubleshooting.
| Requirement | Notes |
|---|---|
| CMake | 3.26+ (cmake_minimum_required in tree) |
| C++ compiler | C++17 (GCC, Clang, MSVC supported in principle) |
| Qt 6 | ≥ 6.10 — components: Core, Gui, Qml, Quick, Network (Quick pulls Gui stack on many platforms) |
| Boost | ≥ 1.70 — unit_test_framework only, for Test_poker when tests are enabled |
| Build backend | Ninja recommended (used by build.sh); Makefile generators work too |
Point CMake at your Qt install prefix (the directory that contains lib/cmake/Qt6):
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/path/to/Qt/6.10.0/gcc_64
cmake --build build -j
ctest --test-dir build --output-on-failureTo configure without tests (no Boost required): -DBUILD_TESTING=OFF.
Convenience script (requires CMAKE_PREFIX_PATH or QT_LIBS pointing at your Qt 6 prefix):
CMAKE_PREFIX_PATH=/path/to/Qt/6.10.0/gcc_64 ./build.shRun (binary name and path):
./build/poker/PokerThe app starts on the lobby; navigate to the table, bots & ranges, solver & equity, training, bankroll & stats, or hand history. The live table page is screens/GameScreen.qml (objectName: game_screen), connected after load so the engine can sync state.
Table stakes, per-seat bot strategy and range text (exported form), per-seat buy-in and related bankroll fields, sit out, solver & equity field values, trainer auto-advance / decision time, and training progress are persisted as JSON rows in a kv table. Completed hands are also stored in normalized hands, actions, and players tables (see SQLite → Parquet). The primary file is ~/.local/share/TexasHoldemGym/Texas Hold'em Gym/texas-holdem-gym.sqlite (override with TEXAS_HOLDEM_GYM_SQLITE). If SQLite cannot be opened, the app falls back to QSettings INI under ~/.config/TexasHoldemGym/ (relational hand-log tables exist only in SQLite). Legacy INI data is migrated into SQLite on first open when possible.
| Document | Contents |
|---|---|
| docs/building.md | Dependencies, CMake configure, tests, card assets script, troubleshooting |
| docs/architecture.md | App shell, QML ↔ C++, modules, persistence (KV + hand log) |
| docs/game-in-code.md | NLHE as implemented: blinds, streets, side pots, stake cap, bankroll |
| docs/sqlite-parquet-python.md | Export SQLite (settings + hand log) to Parquet for Python / DuckDB / Polars |
| docs/ci.md | GitHub Actions: which jobs run on which branches |
| docs/github-actions-aws-amplify.md | GitHub Actions secrets and deploy to AWS Amplify (marketing site) |
ctest --test-dir build --output-on-failureVerbose output (each suite and case, timings):
ctest --test-dir build -R poker.unit -VOr run the binary directly:
./build/poker/poker/tests/Test_poker --log_level=test_suite --report_level=detailedWhen BUILD_TESTING is on, Boost.Test builds Test_poker from translation units under poker/poker/tests/ (see CMakeLists.txt), including persistence, hand-log batching, hand-history integration, engine smoke tests, bots, and equity.
