Moregames#96
Merged
Merged
Conversation
folkengine
added a commit
that referenced
this pull request
May 16, 2026
* 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. * bump
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.