Skip to content

Fix MJAI replay start_kyoku wall initialization - #162

Merged
smly merged 1 commit into
smly:mainfrom
hong0311:fix/mjai-replay-start-kyoku-wall-init
Mar 10, 2026
Merged

Fix MJAI replay start_kyoku wall initialization#162
smly merged 1 commit into
smly:mainfrom
hong0311:fix/mjai-replay-start-kyoku-wall-init

Conversation

@hong0311

Copy link
Copy Markdown
Contributor

Summary

Fix an off-by-one bug in MJAI replay initialization.

apply_mjai_event(start_kyoku) was leaving replay state in the post-dealer-draw position, even though MJAI logs emit the dealer's first draw as a separate tsumo event. When that logged tsumo was applied, the wall became one tile too short for the rest of the round.

This mostly goes unnoticed, but it breaks legality checks near the end of the hand where rules depend on the remaining wall count. In the reproduced case, a real chi window was reconstructed as Ron/Pass, and select_action_from_mjai(...) failed to resolve the source event.

What changed

  • Reset 4-player MJAI replay state to the correct pre-dealer-draw wall length in start_kyoku
  • Apply the same fix to 3-player replay state
  • Reset round-scoped replay fields during start_kyoku so replay starts from a clean round state
  • Add regression tests covering the pre-tsumo wall length in both 4p and 3p

Why this fixes the bug

For MJAI replay, the correct sequence is:

  • start_kyoku -> wall is still pre-dealer-draw
  • first tsumo -> consume exactly one tile

Before this patch, replay effectively started one step too late, so the first logged tsumo consumed an extra tile and shifted the rest of the round out of sync.

Repro

Using 2024010109gm-00a9-0000-1fe4306c.json:

  • before this patch, after player 2 discarded 9s, seat 3 saw Ron/Pass
  • after this patch, seat 3 correctly sees Chi/Pass
  • select_action_from_mjai({"type":"chi","actor":3,"target":2,"pai":"9s","consumed":["7s","8s"]}) now resolves successfully

Testing

  • cargo test -q apply_mjai_event_start_kyoku -- --nocapture
  • cargo test -q test_apply_mjai_event_honor_and_red_tiles -- --nocapture

Manual verification:

  • converted the repro paipu to MJAI events
  • replayed the failing round via apply_mjai_event(...)
  • confirmed the response window now matches the source chi

@hong0311
hong0311 marked this pull request as ready for review March 10, 2026 09:08
@smly
smly self-requested a review March 10, 2026 09:35
@smly smly self-assigned this Mar 10, 2026
@smly smly added bug Something isn't working core labels Mar 10, 2026
@smly smly added this to the v0.5.0 milestone Mar 10, 2026
@smly

smly commented Mar 10, 2026

Copy link
Copy Markdown
Owner

@hong0311 Thanks for the PR! This looks like a solid and important bug fix for the MJAI replay. Really appreciate it! I'll verify the repro using the paifu mentioned in the description just to be safe.

P.S. Now I remember — I originally implemented replay for mjsoul logs first, and added MJAI log replay later. In mjsoul logs, the dealer receives 14 tiles in the start_kyoku equivalent. That's exactly where this off-by-one came from...

@smly smly left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

LGTM!

self.is_after_kan = false;
self.riichi_sutehais = [None; 4];
self.last_tedashis = [None; 4];
self.wall.tiles = vec![0; 136 - 13 * 4];

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Just to note: the minimal fix for the off-by-one is self.wall.tiles = vec![0; 136 - 13 * 4] (and the corresponding line for 3p). The rest are preventive resets and regression tests, which are welcome.

@smly
smly merged commit a2cedc7 into smly:main Mar 10, 2026
7 checks passed
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants