Add four-player Riichi Mahjong (single hand) - #1573
Open
jaisinha77777 wants to merge 1 commit into
Open
Conversation
Python-only implementation of one hand of four-player Japanese Riichi Mahjong: full deal/draw/discard cycle, riichi declaration, and calling (chi/pon/kan/ron) implemented as sequential priority-ordered polling after each discard (Ron > Pon/Kan > Chi, multi-ron supported), since the real-time interrupt semantics of calling have no direct mapping onto OpenSpiel's simultaneous or turn-based dynamics (see google-deepmind#979). Hand evaluation (mahjong_riichi_utils.py) is a self-contained module covering the standard yaku set, fu/han computation, dora/aka-dora/ ura-dora, and the mangan-through-yakuman point table, so it can be unit-tested independently of game flow. Scope: one hand per episode (deal through win or draw), not a full multi-hand match with dealer rotation/score carryover.
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.
Per #843 (see comment there flagging this before opening the PR, per #1511's guidance for larger contributions).
Adds
python_mahjong_riichi: one hand of four-player Japanese Riichi Mahjong, Python-only.The calling problem. Pon/Chi/Kan/Ron is a real-time interrupt mechanic with no direct mapping onto OpenSpiel's simultaneous-move or turn-based dynamics — there's an old, unresolved thread on exactly this at #979. This implements it as sequential, priority-ordered polling after each discard: every Ron-eligible player is asked first, in turn order (multiple simultaneous ron is supported); only if nobody rons is the single Pon/Kan-eligible player (if any) asked; only if nobody calls that is the single Chi-eligible player (the discarder's next player) asked. This reproduces standard priority (Ron > Pon/Kan > Chi) without requiring true real-time simultaneity.
Scoring (
mahjong_riichi_utils.py, kept separate from game flow so it's independently unit-testable): standard hand-shape decomposition (4 sets + pair, chiitoitsu, kokushi), the standard ~25 named yaku, fu calculation (wait type, open/closed triplet-vs-kan distinction, shanpon-on-ron vs shanpon-on-tsumo, double-wind pairs), dora/aka-dora/ura-dora, and the mangan-through-yakuman point/payment tables. The common yakuman are covered (kokushi, suuankou, daisangen, shou/dai-suushii, tsuuiisou, chinroutou, ryuuiisou, suukantsu, chuuren poutou, tenhou/chiihou); a handful of rare local-rule yaku (e.g. renhou) are intentionally not included.Also implemented: riichi declaration with furiten tracking (both permanent, from a player's own discards, and temporary, from declining a legal ron), chankan (robbing a kan), and the abortive draws (kyuushu kyuuhai, four-kan, four-riichi, four-wind-discard).
Scope: one hand per episode (deal through win or exhaustive draw), not a full multi-hand match with dealer rotation and score carryover across hands — same pattern as e.g.
leduc_pokermodeling one hand rather than a session.returns()is the point swing for the hand.Testing:
mahjong_riichi_utils_test.py: 27 tests on hand-shape decomposition, fu/yaku detection (including a regression test for a sanshoku-doujun bug caught along the way — it originally only matched runs starting at "1"), dora counting, and the payment tables, checked against hand-derived reference values.mahjong_riichi_test.py: 9 tests covering the deal structure, action-encoding consistency, a directed Tenhou-tsumo scenario, a directed ron + furiten scenario (confirming furiten blocks ron across a player's entire wait-set, not just the declined tile), riichi discard-locking,pyspiel.random_sim_testwith serialization, and a zero-sum-returns check across many full random games.generate_playthrough.replay.open_spiel/python/games/__init__.py,CMakeLists.txt, andpyspiel_test.py's expected-games list; added a row togames.md.Happy to iterate on the calling-priority design in particular, since that's the part without existing precedent in the codebase.