Skip to content

fix(3p): correct dead wall layout and rinshan draw logic (#183)#186

Merged
smly merged 9 commits intomainfrom
fix/3p-rinshan-draw-bugfix
Mar 17, 2026
Merged

fix(3p): correct dead wall layout and rinshan draw logic (#183)#186
smly merged 9 commits intomainfrom
fix/3p-rinshan-draw-bugfix

Conversation

@smly
Copy link
Copy Markdown
Owner

@smly smly commented Mar 17, 2026

Fix a bug where dora indicator tiles could be consumed by rinshan draws in 3P mode, causing a tile type to appear more than 4 times (#183). Plus,

  • Refactor both 3P and 4P to use a drawable_count counter instead of comparing tiles.len() against a magic number
  • Fix an off-by-one in replay initialization that made the last kita/riichi incorrectly illegal

Root cause

In 3P mahjong, both kan and kita (north extraction) draw rinshan tiles from the dead wall. The old implementation allocated only 4 rinshan slots (same as 4P), but 3P requires 8 (4 kan + 4 kita). After the 4th rinshan draw, tiles.remove(0) consumed dora indicator tiles, making them appear both on the dead wall and in a player's hand.

Validation

  • MjSoul 3P paishan validation: 1,814 kyoku, 60,387 draws (55,517 normal + 4,870 rinshan), 0 failures
  • validate_logs.py 3P: 5000/5000 passed
  • validate_logs.py 4P: 5000/5000 passed

Closes #183

@smly smly added this to the v0.5.0 milestone Mar 17, 2026
@smly smly self-assigned this Mar 17, 2026
@smly smly added bug Something isn't working priority: high core labels Mar 17, 2026
@smly smly changed the title WIP: fix(3p): prevent rinshan draws from consuming dora indicator tiles fix(3p): correct dead wall layout and rinshan draw logic (#183) Mar 17, 2026
@smly smly marked this pull request as ready for review March 17, 2026 06:43
@smly smly requested a review from Copilot March 17, 2026 06:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a 3P (sanma) wall-layout bug where rinshan draws could consume dora indicator tiles (leading to an indicator tile type appearing “5 times”), and refactors wall exhaustion logic in both 3P and 4P to use an explicit drawable_count rather than tiles.len() magic-number checks.

Changes:

  • 3P: Adjust wall layout / rinshan draw path to prevent consuming dora/ura indicator tiles; add regression tests in WallState3P.
  • 3P + 4P: Introduce and plumb drawable_count through draw/exhaustion/riichi/haitei/houtei logic and replay event handling.
  • Tests + replay init: Update unit tests and replay initialization to keep drawable_count in sync (fixing the reported off-by-one legality issue).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
riichienv-core/src/state_3p/wall.rs Reworks 3P indicator indexing and adds draw_rinshan_tile() plus regression tests for issue #183.
riichienv-core/src/state_3p/sanma.rs Switches kita legality and rinshan draw to use drawable_count and draw_rinshan_tile().
riichienv-core/src/state_3p/mod.rs Updates 3P riichi/haitei/houtei/kan draw/deal flow to use drawable_count; initializes the counter per-round.
riichienv-core/src/state_3p/legal_actions.rs Aligns 3P legal-action gates (riichi/kan/haitei/houtei/pon/kan) with drawable_count.
riichienv-core/src/state_3p/event_handler.rs Keeps replay-driven wall consumption consistent by decrementing drawable_count when popping wall tiles.
riichienv-core/src/state/wall.rs Adds drawable_count to the 4P wall state and resets it on shuffle/load.
riichienv-core/src/state/mod.rs Refactors 4P riichi/haitei/houtei/kan draw/deal flow to use drawable_count; initializes the counter per-round.
riichienv-core/src/state/legal_actions.rs Aligns 4P legal-action gates (riichi/kan/chi/haitei/houtei/pon/kan) with drawable_count.
riichienv-core/src/state/event_handler.rs Keeps replay-driven wall consumption consistent by decrementing drawable_count when popping wall tiles.
riichienv-core/src/replay/mod.rs Fixes replay initialization accounting by incrementing drawable_count when pushing back the oya draw tile.
riichienv-core/src/replay/mjai_replay.rs Updates documentation comment to match the “non-drawable reserve” concept.
riichienv-core/src/tests.rs Updates sanma unit tests to set drawable_count after overriding the wall tiles.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread riichienv-core/src/state_3p/wall.rs
Comment thread riichienv-core/src/state_3p/sanma.rs Outdated
Comment thread riichienv-core/src/state_3p/mod.rs Outdated
Comment thread riichienv-core/src/state_3p/wall.rs Outdated
@smly smly merged commit 4dca7b9 into main Mar 17, 2026
7 checks passed
@smly smly deleted the fix/3p-rinshan-draw-bugfix branch March 17, 2026 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core priority: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][3P] The Dora indicator tile appears more than 4 times

2 participants