Commit b44ed88
authored
More Games (#97)
* Moregames (#96)
* Added EPICS for adding other poker games
* EPIC-29: variant engine foundation (Phases 1-11) + defect note
* EPIC-30: Fixed-Limit Hold'em (Phases 1-11)
* EPIC-31: Pot-Limit Omaha Hi (Phases 1-10)
* EPIC-31: Pot-Limit Omaha Hi (Phases 1-10)
* ...
* EPIC-32: Seven-Card Stud Hi (Phases 1-13)
EPIC-32 implementation complete. All 13 phases shipped (Phase 12 as live-play smoke; replay round-trip deferred to v1.1 with rationale
documented).
┌────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────┐
│ Phase │ Result │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 1: GamePhase Stud variants + bet-tier │ ✅ Stud3rd..Stud7th + stud_street_index + next_stud_street │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 2: Antes + family-dispatched forced │ ✅ act_antes + TableAction::BetAnteForced │
│ bets │ │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 3: Visibility-aware dealing │ ✅ deal_card_to_seat_with_visibility, deal_stud_3rd_street, deal_stud_street │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 4: Bring-in selection + posting │ ✅ lowest/highest_upcard_seat, third_street_extreme_upcard_seat, act_bring_in, │
│ │ TableAction::StudBringInPost │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 5: Stud action order │ ✅ best_visible_hand_seat with phase-aware upcard truncation; │
│ │ VisibleHandMode::HighStud/LowRazz │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 6: stud_hi_from_seats + session │ ✅ PokerSession::start_hand + advance_street Stud branches │
│ dispatch │ │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 7: Stud showdown via Seven::eval │ ✅ stud_river_case_eval (bypasses build_game's Board requirement) │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 8: Mid-hand Stud equity │ ✅ 3- and 4-card heuristic bucket in RuleBasedDecider::hand_equity │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 9: HandHistory visibility serde │ ✅ PlayerEntry.hole_cards_visibility, Stakes.bring_in, PlayerEntry::to_seven, replay routes │
│ │ Stud through stud_hi_from_seats │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 10: for_stud_hi factory + profiles │ ✅ tight_aggressive_stud_hi.yaml + loose_passive_stud_hi.yaml │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 11: │ ✅ 20-hand bot-vs-bot demo │
│ examples/interactive_play_stud_hi.rs │ │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 12: Stud replay-consistency test │ ✅ Live smoke + YAML field round-trip (replay round-trip deferred to v1.1) │
├────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────┤
│ 13: corrigendum + verification │ ✅ │
└────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘
Final pin tests:
- 9057 lib tests pass (+3 from EPIC-31: for_stud_hi marker + 2 YAML load tests)
- 657 doc tests pass (+5)
- 4/4 replay_consistency tests pass — NLHE, FLHE, PLO + Stud live-smoke
- interactive_play_stud_hi 20 hands run end-to-end
- bot_selfplay NLHE regression-free
- Clippy clean on every EPIC-32 file
Files changed: 10 modified, 3 new (2 YAML + 1 example). ~1279 lines added.
★ Insight ─────────────────────────────────────
- Stud replay round-trip surfaced a deep architectural gap: live action ordering depends on the per-street visible-card set, which doesn't
survive a one-shot inject_hole_cards injection of all 7 cards. Phase-aware truncation in best_visible_hand_seat +
third_street_extreme_upcard_seat aligns live and replay for bring-in / first-to-act selection, but the deeper issue is that Streets
(preflop/flop/turn/river) doesn't carry stud street action lists separately. The proper fix is either incremental dealing during replay or
a StudStreets enum — both are v1.1 polish.
- The hand-loop "growth" mostly happened in two methods: PokerSession::start_hand and PokerSession::advance_street both gained Stud-family
branches at the top, leaving the Hold'em-family path untouched. This is the right shape — variant-specific behavior at the dispatch layer,
shared infrastructure (bring_it_in, apply_action, side-pot resolution) underneath.
- The BetAnteForced table-action variant already existed from earlier work but wasn't wired. Phase 2's act_antes finally exercises it. This
is the third time during the variant initiative that EPIC-29's foundation paid for itself: pre-existing scaffolding (ForcedBets.bring_in,
SeatHand, Visibility, STUD_HI_STREETS, BetAnteForced) was waiting to be activated.
─────────────────────────────────────────────────
* EPIC-33: Razz (A-5 Lowball) [Phases 1-7]
Wires Razz showdown evaluation on top of EPIC-32's Stud engine.
Razz reused ~95% of Stud's infrastructure (bring-in, action order,
dealing, is_game_over, replay visibility) — the only load-bearing
work was the CaliforniaHandRank → Eval bridge.
- Phase 1: Eval::from_razz_rank + Eval::from_seven_razz; new
HandRankName::RazzLow + HandRankClass::Lowball variants.
- Phase 2: razz_river_case_eval + dispatch split (StudHi vs Razz)
in river_case_eval_for_variant + build_eval_for_seat.
- Phase 3: razz_from_seats constructor (mirrors stud_hi_from_seats).
- Phase 4: BotProfile::for_razz factory + 2 reference YAML profiles.
- Phase 5: examples/interactive_play_razz.rs — 20-hand smoke.
- Phase 6: HandHistory replay routes HandVariant::Razz through
razz_from_seats; new test_razz_bot_selfplay_replay_roundtrip.
- Phase 7: Verification + EPIC-33 corrigendum.
Inversion math turned out unnecessary — HandRank::cmp is already
inverted, cancelling CaliforniaHandRank's lower-is-better ordering.
Razz full replay round-trip deferred to v1.1 (incremental-dealing
gap shared with Stud Hi).
EPIC-33: Razz (A-5 Lowball) [Phases 1-7]
Wires Razz showdown evaluation on top of EPIC-32's Stud engine.
Razz reused ~95% of Stud's infrastructure (bring-in, action order,
dealing, is_game_over, replay visibility) — the only load-bearing
work was the CaliforniaHandRank → Eval bridge.
- Phase 1: Eval::from_razz_rank + Eval::from_seven_razz; new
HandRankName::RazzLow + HandRankClass::Lowball variants.
- Phase 2: razz_river_case_eval + dispatch split (StudHi vs Razz)
in river_case_eval_for_variant + build_eval_for_seat.
- Phase 3: razz_from_seats constructor (mirrors stud_hi_from_seats).
- Phase 4: BotProfile::for_razz factory + 2 reference YAML profiles.
- Phase 5: examples/interactive_play_razz.rs — 20-hand smoke.
- Phase 6: HandHistory replay routes HandVariant::Razz through
razz_from_seats; new test_razz_bot_selfplay_replay_roundtrip.
- Phase 7: Verification + EPIC-33 corrigendum.
Inversion math turned out unnecessary — HandRank::cmp is already
inverted, cancelling CaliforniaHandRank's lower-is-better ordering.
Razz full replay round-trip deferred to v1.1 (incremental-dealing
gap shared with Stud Hi).
* fix: accept Axs/Axo/Ax as aliases for A2s+/A2o+/A2+
The combo parser at src/analysis/gto/combo.rs only knew explicit
anchor tokens (A2s+, A3s+, etc.), so any-suited-Ace shorthand silently
fell through to "Unable to process Axs" stdout noise and dropped the
range entry. loose_passive.yaml's open_raise field tripped this.
Two-part fix:
- loose_passive.yaml: Axs -> A2s+ (canonical form).
- combo.rs: also accept "axs" / "axo" / "ax" as aliases that expand to
the same Combo constants. Both notations now produce identical
parsed ranges; YAMLs can use whichever reads better.
Adds 6 new parametrized rstest cases (both casings).
* docs: spec for position
indicators in interactive_play examples
* feat(interactive_play): add position_tag helper with HU collapse
* feat(interactive_play): show position tags on Stacks line
* feat(interactive_play): add position tag column to action lines
* feat(interactive_play): show Position field in Your turn box
* docs: spec scope trim + implementation plan
* needs work
* fix(bot): gate YAML-loading tests behind bot-profiles feature
The PLO/Stud Hi/Razz/FLHE/NLHE *_yaml_loads tests call
BotProfile::from_yaml_str, which is gated behind feature = \"bot-profiles\".
Without the matching cfg on the tests, --no-default-features breaks the
test build in CI.
* bump1 parent 7a1064a commit b44ed88
49 files changed
Lines changed: 8415 additions & 86 deletions
File tree
- .claude
- data/bots
- flhe
- plo
- razz
- stud_hi
- docs
- superpowers
- plans
- specs
- examples
- src
- analysis
- gto
- bot
- casino
- table
- games
- play
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
| 53 | + | |
| 54 | + | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
127 | 133 | | |
128 | 134 | | |
129 | 135 | | |
| |||
132 | 138 | | |
133 | 139 | | |
134 | 140 | | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
135 | 184 | | |
136 | 185 | | |
137 | 186 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
0 commit comments