-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Add a match result analysis API to the RiichiEnv object so users can easily access per-round and per-match aggregate statistics for each player's key actions.
Background
The RiichiEnv class (defined in riichienv-python/src/env.rs, exposed via PyO3) already tracks per-step game state including hands, discards, melds, riichi_declared, win_results, and score_deltas. The WinResult class provides detailed win-hand scoring (han, fu, yaku list, ron/tsumo). However, there is no built-in way to query aggregate statistics across rounds or across an entire match.
Currently, users must manually iterate through game logs or observations to compute basic statistics, which is tedious and error-prone.
Proposed API
Per-round (kyoku) statistics for each player:
| Statistic | Description |
|---|---|
deal_in (houjuu) |
Whether the player dealt into another player's winning hand (ron) |
riichi |
Whether the player declared riichi |
furo (melds/calls) |
Whether the player made any open calls (chi/pon/kan) |
win |
Whether the player won the round (and by tsumo or ron) |
tenpai |
Whether the player was tenpai at exhaustive draw |
Per-match aggregate statistics for each player:
| Statistic | Description |
|---|---|
deal_in_count |
Total number of rounds where the player dealt in |
riichi_count |
Total number of riichi declarations |
furo_count |
Total number of rounds where the player made open calls |
win_count |
Total number of round wins |
tsumo_count |
Total number of tsumo wins |
ron_count |
Total number of ron wins |
final_score |
Final score |
final_rank |
Final placement (1st, 2nd, 3rd, 4th) |
Example Usage
env = RiichiEnv()
# ... run a full game ...
stats = env.match_stats()
# Per-player aggregates
for player in range(4):
p = stats.player(player)
print(f"Player {player}: deal-ins={p.deal_in_count}, riichi={p.riichi_count}, furo={p.furo_count}")
# Per-round detail
for kyoku in stats.kyokus():
for player in range(4):
r = kyoku.player(player)
print(f" Player {player}: deal_in={r.deal_in}, riichi={r.riichi}, furo={r.furo}")Implementation Notes
- Statistics should be computed lazily or accumulated during
step()calls to avoid redundant iteration. - Consider whether this should live in the Rust core (for performance with large batches) or as a Python-level wrapper.