Skip to content

About

Hangzhou Mahjong training and evaluation framework with public-information Transformers, paired branch reinforcement learning, and the r2600 checkpoint.

Resources

Stars

186 stars

Watchers

7 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Hangzhou Mahjong with Public-Information Transformers and Paired Branch Reinforcement Learning

Overview

This project provides a Hangzhou Mahjong agent, its training and evaluation framework, and results from a frozen internal opponent pool. Hangzhou Mahjong combines hidden information, variable-length matches, persistent dealer status, and multiplicative scoring. These properties make decisions depend on both local hand structure and public table history. The 52.01-million-parameter policy combines a tile-relation Transformer, a causal event encoder, legal-action queries, public tactical successor features, and compact opponent memory. The reported checkpoint inherits an already trained policy, receives supervised action fine-tuning, and continues with paired branch reinforcement learning. Each eligible decision on a reference trajectory produces five exploratory continuations. Their realized scores are compared with a reference over the same game window, and an empirical clipped objective updates the exploration distribution using its recorded temperature and tactical bias. Evaluation rotates complete tables through all four seats and reports a fixed table-length-weighted net score.

In a completed 36-participant tournament comprising 1,081,008 games, with 120,112 seat-games per participant, the released r2600 checkpoint ranked first under the predefined weighted score, at +0.452171 per seat-game. The next participant scored +0.430258; their difference was +0.021914, with an exploratory 50% bootstrap interval of [−0.024367, +0.069381]. The interval does not establish a reliable separation between the two. This repository contains the training framework, game simulator and evaluator, and the selected r2600 weights. It supports running the released policy and evaluating user-supplied checkpoints. Historical rule opponents, other neural weights, and the demonstration corpus are not included.

Keywords: imperfect-information games; Mahjong; reinforcement learning; causal memory; structured exploration; policy optimization.

1. Problem and scope

The objective is to maximize net score in a four-player local Hangzhou Mahjong environment. Winning frequency alone is insufficient: the payoff of a win varies with the hand pattern, action chain, and dealer relationship. A policy must also account for how its current decisions affect the next round and future dealer status.

The report documents three engineering contributions, without claiming that their individual benefits have been experimentally isolated:

  1. A public-information policy. Hand structure, legal actions, public events, the player's own past decisions, and completed-round summaries are represented separately and fused by attention.
  2. Paired short-horizon exploration. Alternative continuations start from the same simulator state as a reference policy, providing a realized comparison without using a learned value function as the branch baseline.
  3. A reproducible tournament protocol. Frozen weights, fixed random plans, four-seat rotations, equal participation, and explicit table-length weights define the reported score.

The simulator is a particular Hangzhou rule set described below. Results are conditional on these rules and the evaluated opponent pool. The project does not claim universal Mahjong strength, human-level performance, or an ablation-proven contribution from each component.

The empirical question answered here is narrow: how do the frozen participants rank under one specified tournament distribution and score? The tournament does not test whether this training method outperforms another method under matched data and compute. The contribution is a concrete system definition, a runnable training/evaluation framework with one checkpoint, and the conditional tournament result.

1.1 Design motivation

The architecture and learning objective address different parts of the decision problem:

Difficulty in this environment Design response Remaining limitation
The current hand does not summarize public behavior across a table A causal event stream, opponent profiles, and completed-round memory accompany the tile representation A richer representation does not by itself prove better hidden-state inference
Legal actions have different structures and consequences Candidate queries read action-specific public successor features Local approximations do not model every possible opponent response
Sparse, multiplicative scores make individual outcomes noisy Exploratory continuations are compared with a reference from the same decision state and return window Paired realized returns remain noisy, and the window omits distant consequences
Scores depend on seat position, opponents, and table length Four-seat mirrored groups, balanced participation, and predefined table-length weights determine evaluation Conclusions remain conditional on the chosen rules and participant pool

These are implementation choices and their motivations. The final tournament evaluates the complete system; it does not isolate the causal effect of each choice.

1.2 Relation to Suphx

Suphx [1] is a relevant reference for organizing a Mahjong system around its decision flow, representations, learning signals, and evaluation. It studies Riichi Mahjong and combines supervised initialization with reinforcement learning. Its reported methods include global reward prediction, oracle-guided training, and policy adaptation during play. The following comparison concerns mechanisms, not playing strength (see [1], Sections 2–5).

Aspect Suphx [1] This system
Decision models Separate convolutional models for five action categories A shared tile/history Transformer with legal-action queries, including the win decision
Training return Learned global reward prediction connects rounds to the final game reward Realized branch-minus-reference net score over at most two games, without a learned critic in this objective
Hidden information during training Oracle access is progressively removed from the policy Policy inputs retain the player's information boundary; hidden counts may be auxiliary labels, and full states execute simulator branches
Adaptation during play Simulation-based parameter updates adapt the policy Parameters stay fixed during evaluation; causal history and public memory update as observations arrive
Evidence Offline experiments and online human-play evaluation One completed tournament among frozen model and rule participants

Public look-ahead features are another connection to Suphx's representation design. Here they are encoded as action-owned successor vectors and bounded one-/two-draw estimates; they do not constitute a full search over hidden states. Different rules, objectives, and evaluation populations preclude a numerical strength comparison with Suphx. This work reports its own architecture and observed tournament results without transferring Suphx's human-performance claims to the released model.

1.3 Simulation, baselines, and policy improvement

Simulation-based rollout methods use a base policy to estimate the consequences of candidate choices and connect this procedure to policy improvement [6]. This system instead samples short exploratory continuations during training and fits a parametric policy with a clipped loss. It does not perform exhaustive rollout action selection during evaluation, and the improvement conditions in [6] do not establish an improvement guarantee for this objective.

PEGASUS [7] studies policy search with a deterministic simulative model and fixed random scenarios. Our pairing similarly reuses a root state and wall-seed plan to reduce uncontrolled differences between a branch and its reference. We do not implement the PEGASUS policy-search procedure or establish its assumptions here. Pairing is not a proof of variance reduction in this environment: different actions can change tile consumption and downstream events.

COMA [8] addresses cooperative multi-agent credit assignment through a centralized critic and a baseline that marginalizes one agent's action. Our reference is a realized deterministic continuation in a competitive, zero-sum game; it is neither that critic nor an action-marginalized counterfactual baseline. The clipped probability-ratio update is inspired by PPO [2], but uses shared continuation returns, stale sampled policies, and outcome-dependent weights. These distinctions matter when interpreting the method as an empirical system design rather than a theoretical policy-gradient result.

2. Game environment and information boundary

The following units are used throughout; the word round in source-code field names can denote either a game or an optimizer iteration, so those units are made explicit in the text.

Term Meaning
Game One deal, from dealing to a self-drawn win or wall exhaustion
Table / match A fixed lineup playing $N$ games with carried scores and dealer state
Seat-game One participant occupying one seat in one game; four seat-games per game
Mirrored group Four complete tables with the lineup rotated through all four seats
Training iteration One sampled batch of reference tables and branches, followed by two optimizer steps
Root / continuation A saved learner decision state / a branch executed from that state

2.1 Rules and settlement

The environment uses 136 tiles: four copies of each of 34 tile types. White dragons serve as wild tiles. Only self-drawn wins are allowed; robbing a kong is not part of this rule set. The final 20 wall tiles are reserved. A kong requires a replacement tile to remain available. A player may make at most two chi melds.

Discarding a wild tile starts a restricted catch-and-discard cycle. During that cycle, the other players cannot chi, peng, or claim an exposed kong, and their discard is restricted to the drawn tile; concealed/additional kongs and self-drawn wins remain subject to their own legality checks. The simulator handles the response priority and action sequencing.

The fan multiplier is

$$ F=H,2^c,2^{I_{\mathrm{four\ white}}},2^{I_{\mathrm{baotou}}}. $$

Quantity or rule Definition in this environment
Ordinary winning hand Four sets (sequences or triplets, including declared melds) and a pair, using white dragons as wilds; $H=1$
Seven pairs A closed 14-tile hand forming seven pairs; $H=2\times2^q$
Luxury count $q$ Number of natural non-white four-of-a-kind groups in the seven-pairs hand, plus one if all four real whites remain and no white is needed to complete a non-white singleton
Wilds in seven pairs Whites first complete non-white singletons; remaining whites must form pairs
Baotou Before the draw, adding any of the 34 tile types completes a legal hand shape; the bonus uses that pre-draw state, including before a kong replacement draw
Piao Discarding a white while in the baotou state; increments both the chain count and the number of whites discarded within that chain
Chain length $c$ Each own kong or qualifying piao increments the chain. An ordinary discard resets the chain and its piao count
Four-white bonus Whites still held at the win plus whites discarded as piao in the current chain equal exactly four

The factors stack. For example, an ordinary baotou win after a two-action chain, without the four-white bonus, has fan $1\times4\times2=8$. Natural quads in seven pairs are hand-pattern bonuses, distinct from declared kongs. The experiment disables the optional restriction that would require a player holding whites to win only through baotou or a kong replacement; ordinary self-drawn wins while holding whites are allowed. Fan is multiplicative, not an additive score.

For winner $w$, loser $j$, dealer $d$, base unit $b=1$, and fan $F$,

$$ p_{j\rightarrow w}=bF \begin{cases} 8,&j=d\ \text{or}\ w=d,\\ 1,&\text{otherwise}. \end{cases} $$

Each of the other three players pays the winner separately. Thus each game's score changes sum to zero. The winner becomes the next dealer; a draw leaves the dealer unchanged. A match contains $N$ games. Branch training uses lengths from 8 to 16: each block of six tables contains one 8-game table, one 16-game table, and four tables whose lengths are drawn uniformly from 9 through 15. The main evaluation instead covers $N\in{1,\ldots,18}$, with the scoring weights defined in Section 6.

2.2 Policy-visible information

At decision time, the policy receives its own hand, public discards and melds, public action events, scores, dealer and round context, and legal actions. It does not receive the wall order or the other players' concealed hands.

There are three distinct uses of information:

Use Available information
Policy input and tactical features The acting player's observation and causally available public history
Supervised auxiliary targets Concealed-state labels, when present in the supplied training dataset
Simulator rollout and score computation Full simulator state, used to execute and settle games

Auxiliary targets are training labels, not policy inputs. Branching clones the simulator state to execute alternative outcomes; the model still observes only its own view. This distinction is necessary when interpreting the paired-return estimate: it is a simulator-based training signal, not access to hidden information during play.

3. Model architecture

The selected checkpoint contains 52,005,062 parameters. It uses the query action head, dynamic match-length conditioning, and public tactical memory.

Component Configuration
Tile/state stream 34 tile tokens plus 2 context tokens
State Transformer 20 blocks, width 448, 7 attention heads
State feed-forward hidden width 896
Causal history Transformer 4 blocks, width 256, 4 heads
History feed-forward hidden width 768
Public event vocabulary 859 entries
History side features 26 values per event
Legal-action query width 256
Action vocabulary 142 actions
Tactical successor vector 720 values
Opponent profile 193 values per opponent
Completed-round summary 304 values per round
Recent-event reader At most 32 events within the current round
Match-position embedding 10 interpolated anchors
Parameters updated in branch RL 51,715,121; value and auxiliary heads are frozen

3.1 Current state and tile relations

The current board is represented by 34 tile-type tokens, each with 101 input channels. Separate tokens represent pooled board context and the current action request. The request combines the action kind, requested tile, relative source seat, match position, and a 202-dimensional context containing scalar context and the legal-action mask.

Self-attention over tile tokens includes learned relation biases. Relations distinguish identical tiles, within-suit rank offsets, equal ranks across suits, wild-tile relationships, and other tile pairs. This supplies a structured inductive bias while leaving the learned policy responsible for the action decision.

Residual blocks use RMS normalization [3] and SwiGLU feed-forward transformations [5]. The model does not run a game-tree search at deployment.

3.2 Causal history and cross-stream fusion

Public event tokens and the player's own decisions form a causal sequence. Event features include token identity, public side information, tile references, and the player's initial hand at the start of each round. Own-decision records encode the observation available when that decision was made and the submitted action.

The history encoder uses rotary position embeddings [4]. The state stream reads the permitted history prefix through gated cross-attention after state blocks 4, 10, and 16, using one-based numbering. An action query also reads history before its final score is produced.

Training assembles complete table histories with a separate visible-prefix boundary for every decision. A decision cannot attend to future public events or future decisions from the same table. At inference, incremental key/value caches avoid repeatedly encoding an unchanged prefix. Training recomputes history representations under the current model parameters and propagates gradients through them.

flowchart LR
    S[Current public observation] --> T[Tile-relation Transformer]
    H[Public events and own decisions] --> C[Causal history Transformer]
    C --> T
    M[Public opponent profiles and completed rounds] --> T
    A[Legal action candidates] --> Q[Action queries]
    X[Public tactical successor features] --> Q
    T --> Q
    C --> Q
    Q --> P[Masked action scores]
Loading

3.3 Legal-action queries and conditional meld decisions

Actions occupy a fixed 142-element space:

Indices Meaning
0–33 Discard a tile type
34–67 Concealed kong
68–101 Added kong
102–135 Exposed kong
136 Peng
137–139 The legal chi alternatives
140 Win
141 Pass

Only legal candidates are assembled as action queries. A query combines the request representation, target tile, supporting tiles, and action type. It reads the current state and permitted history, then produces a scalar score. Invalid actions are masked. Index 142 is used internally for batch padding and is never an executable action.

When an exposed-kong response also allows peng, the implementation composes two conditional distributions:

$$ P(\text{kong})=P_g(\text{accept}),\quad P(\text{peng})=P_g(\text{pass})P_p(\text{accept}),\quad P(\text{pass})=P_g(\text{pass})P_p(\text{pass}). $$

Both conditional predictions use the same historical cutoff. Rejecting the kong does not fabricate an extra historical event or training decision.

3.4 Public tactical successors

Legal candidates can lead to multiple meaningful local successor states. The feature builder constructs these successors using only the public observation and the acting player's hand. It represents ordinary/seven-pairs progress, improving tiles, structurally winning tiles, publicly unseen counts, legal winning opportunities, immediate fan and income, meld status, action-chain state, and match context.

A successor vector contains 71 scalar features with availability indicators and 17 tile-wise fields over 34 tile types:

$$ d_{\text{successor}}=2\times71+17\times34=720. $$

The availability channels distinguish an unknown or inapplicable quantity from a genuine zero. Count/distance quantities use fixed units; selected score and fan quantities use logarithmic encoding.

The feature builder also contains bounded local one-/two-draw approximations. These estimates use public unseen-tile counts and hand-shape calculations, not the actual future wall. They are features for the policy and exploration mechanism; they are not calibrated probabilities of winning an entire game.

Each candidate query attends only to successor rows owned by that candidate. Consequently, successor representations remain aligned with the action whose consequences they describe.

3.5 Opponent memory and variable-length matches

Opponent memory is updated from public events and completed settlements. It contains cumulative statistics, a bounded recent-event summary, smoothed discard distributions, and availability/context metadata. Each of the three opponents has a 193-dimensional profile. Completed rounds produce 304-dimensional summaries. A summary becomes visible only after its round has finished.

A separate reader attends to at most the latest 32 history events from the current round. This supports local response context without replacing the full causal history stream.

For round index $t\in{0,\ldots,N-1}$, a 10-anchor embedding uses the continuous position

$$ u_t=\frac{9t}{\max(N-1,1)}. $$

The neighboring anchor vectors are linearly interpolated. A single-game match uses the final anchor explicitly. Additional continuous horizon features condition the current-state and history streams on match length and remaining horizon.

4. Supervised action learning

4.1 Recorded training recipe for r2600

The released checkpoint was not trained from scratch in the final fine-tuning run. Its immediate parent was an already trained policy at iteration 2537. Four epochs of action-only supervised fine-tuning supplied the adopted weights, after which branch RL continued through iteration 2600. The RL continuation retained the parent RL optimizer state, not the supervised optimizer. The iteration number is a lineage label, not a count of all optimization used to produce the model.

Item Recorded setting or quantity
Demonstration source Retained action logs from online games, 27 September–8 October 2026; teachers were the top five eligible entries in saved daily standings after excluding the project agent. The 27 September selection used the 28 September standings
Teacher coverage 18 distinct selected teacher identities across the period; selection indicates relative standing in those logs, not an independently established skill level
Accepted data 57,262 unique labeled decisions in 2,313 player-history prefixes, drawn from 2,180 distinct recorded table/match identifiers (the source field game_id may span multiple games) and 288 rooms; prefixes can end before the table does and are not 2,313 complete independent tables
Action coverage 45,051 discards; 4,398 passes; 3,358 peng; 3,004 chi; 1,213 wins; 238 kongs (125 added, 89 exposed, 24 concealed)
Inclusion and history Executed choices and uniquely reconstructible refusals; unresolved legal timeouts or automatic actions terminate the usable later prefix. Another 96 forced-action rows provide history but no supervised loss
Coverage restriction A teacher prefix stops before that player first becomes dealer, because its initial concealed 13-tile state cannot be resolved from the retained log at that boundary; 1,976 such truncation boundaries are recorded. This fine-tuning corpus consequently contains nondealer decisions, not balanced dealer/nondealer coverage
Split All accepted decisions used for training; no held-out validation split or held-out imitation accuracy in this fine-tuning stage
Actual fine-tuning objective Unit-weight hard-action cross-entropy, coefficient 1; value and auxiliary loss coefficients 0, with those heads frozen; no suit augmentation in this stage
Optimizer AdamW, learning rate $10^{-4}$, epsilon $10^{-8}$, zero weight decay, gradient norm limit 1.0, global batch of 128 decisions (last batch smaller), BF16 forward computation
Adopted supervised budget Four complete epochs: 229,048 decision presentations and 1,792 optimizer updates; two RTX 5090 learner GPUs
Supervised selection Seven epochs were evaluated against the fixed pre-fine-tuning policy using 1,000 actual tables per epoch, with table lengths 8–16. Epoch 4 had the best observed score; epochs 3/4/5 and the initial policy also entered a selection tournament with the then-current pool, where epoch 4 ranked first
Final RL segment Iterations 2538–2600 inclusive: 63 batches, 756 reference tables, 99,758 roots, 498,790 branch continuations, 3,374,171 recorded learning decisions, and 126 optimizer updates
RL hardware and timing Two RTX 5090 learner GPUs and two eight-GPU sampling machines. Summed recorded training-iteration time for this segment was 3,542.23 seconds, including sampling waits and saves; its learning-update subtotal was 1,646.06 seconds. These exclude evaluation and are not end-to-end project costs

The first four supervised epochs took 377.29 seconds in aggregate including their setup and saves, excluding data preparation and model-selection games. This is the compute on the adopted path; the seven-epoch search and its evaluation cost extra. Epoch 4's 90.59% action agreement is a training statistic, not held-out accuracy. The RL quantities above are sums of recorded per-batch counts; raw table identifiers were not independently deduplicated in this summary.

During the final RL segment, three opponents were sampled uniformly with replacement from a 25-entry pool: 12 frozen older neural models, 12 rule policies, and the earlier current-family r1500 checkpoint. The learner's seat varied with the table schedule. This is substantial overlap between training opponents and final evaluation participants, not an unseen-opponent benchmark. The reference and five branches for a packet use the same frozen learner version. Sampling ahead of learning produced observed lag values of 0–3 completed iterations relative to the learner state immediately before its next update; stored behavior probabilities are used by the loss.

The inherited parent itself came from prior supervised and RL training. This report does not reconstruct its complete pre-2537 data/compute budget or every earlier model-selection decision. Therefore four supervised epochs plus 63 RL iterations is only a documented final training segment, not the total cost of obtaining r2600. Neither the demonstration corpus nor all ancestral checkpoints are included. The final 36-participant tournament is also a checkpoint-selection result, not an untouched confirmation set.

4.2 Supplied supervised-training framework

The supplied general-purpose supervised implementation accepts complete-table datasets with action labels or weighted teacher action distributions. Its optional features below are framework capabilities; they must not be read as additional objectives used in the action-only fine-tuning stage above. Let $y_t(a)$ be a target distribution over legal actions and $w_t$ its validity/importance weight. The policy term is

$$ L_{\mathrm{policy}}= -\frac{\sum_t w_t\sum_a y_t(a)\log\pi_\theta(a\mid o_{\leq t})} {\max(1,\sum_t w_t)}. $$

An optional value regression target and auxiliary count-classification targets support representation learning:

$$ L_{\mathrm{sup}}= L_{\mathrm{policy}}+\lambda_v L_{\mathrm{value}} +\frac{\lambda_{\mathrm{aux}}}{2} \left(L_{\mathrm{opponent\ counts}}+L_{\mathrm{wall\ counts}}\right). $$

The auxiliary head predicts five count categories, 0–4, for each tile type, covering three opponents and the wall. These labels remain outside the inference input.

The trainer groups data by complete tables, supports separate training/validation partitions, and optionally permutes the three suits consistently across observations, actions, masks, and history. It supports BF16 computation, activation checkpointing, distributed data parallelism, and resumable model/optimizer/random-state checkpoints.

The historical demonstration corpus and its preprocessing inputs are not included. The supervised trainer is supplied for compatible user-provided data; the selected weights cannot be regenerated from this repository alone.

5. Paired branch reinforcement learning

5.1 Reference trajectories and decision roots

Each sampling batch contains $G=12$ separately seeded reference tables. A table fixes its lineup, random wall plan, initial dealer, match length, and policy random streams. The reference learner follows the deterministic policy.

An eligible learner decision has more than one legal action. The simulator state and policy history are captured immediately before that decision. Duplicate callbacks for an already-resolved conditional meld response do not create extra roots. From each root, the sampler executes five separately sampled exploratory continuations. They have separate action random streams but share the root and reference, and their direction choices are partly coupled. They are not five statistically independent samples.

Exploration and learning decisions apply only through the remainder of the current game. At its end, exploration is cleared; the immediately following game, if present, is played with deterministic learner actions for settlement only. The return covers at most these two games and stops at the end of the table. This permits a limited effect from the next dealer state without rolling out to the end of every match.

Algorithm 1 — One paired-branch training iteration

1. Fix a behavior checkpoint, frozen opponent pool, and sampling seeds.
2. For each of 12 tables:
   a. Sample three opponents with replacement and fix seats, dealer,
      table length, and the per-game wall plan.
   b. Run the deterministic reference table and save eligible learner roots.
   c. At each root, construct five exploration profiles (Section 5.2).
      For each profile, clone the root, sample learner actions until the
      current game ends, then settle one further game deterministically
      if the table has another game. Opponent policies stay fixed.
   d. Store current-game learning decisions, their behavior probabilities
      and biases, and branch/reference scores over the same game window.
3. Compute one paired return and outcome multiplier for each continuation.
4. Randomly split each table's roots into two disjoint halves.
5. Process each half once with the stored behavior distributions and the
   weighted clipped objective; make one optimizer update per half.

Multiple roots can share reference history and continuation outcomes. Counts of branch decisions therefore measure optimization workload, not independent games or independent statistical evidence.

5.2 Structured behavior distributions

For branch $b$, legal action $a$, policy score $z_\theta(a)$, temperature $T_b$, and bounded tactical rank bias $B_b(a)$,

$$ q_{\theta,b}(a\mid o)= \operatorname{softmax}_{a\in\mathcal A(o)} \left(\frac{z_\theta(a)}{T_b}+\lambda_b B_b(a)\right). $$

For the exposed-kong/peng compound response in Section 3.3, $z_\theta(a)$ is the log of the composed action probability. Temperature and tactical bias are applied after composing the two conditional predictions, not separately to each conditional distribution before multiplication. The ordinary action path uses its masked model scores.

The reference configuration accompanying r2600 is:

Branch Temperature Bias strength Direction selection
1 7.2 0 Exploration without tactical bias
2 14.4 0 Higher-temperature exploration without tactical bias
3 1.0 $\log 2$ One tactical direction
4 1.0 $\log 4$ A direction from a different eligible family
5 1.0 $\log 2$ A mixture of two directions

The distribution is also conditioned on a direction vector and a local plan state; these arguments are suppressed in $q_{\theta,b}(a\mid o)$. Families are $A=(A1,A2,A3)$, $B=(B1,\ldots,B5)$, $C=(C1,\ldots,C4)$, and $D=(D1,\ldots,D5)$. Branch 3 samples a family uniformly, then a direction uniformly within it. Branch 4 excludes that family before drawing its own. Branch 5 samples two distinct families and one direction from each, mixing their weights with $\alpha\sim U(0.25,0.75)$ and $1-\alpha$. B1 and B3 are excluded for roots with declared melds. If the learner subsequently melds, their weights transfer to A1. Profiles persist within a game; events update plans rather than redrawing a direction at each decision.

Direction scores. All quantities below come from a public hypothetical successor $x$, not the true wall. Let $u_t$ be unseen copies of tile type $t$, $U=\max(1,\sum_tu_t)$, $d_o,d_7$ the ordinary/seven-pairs hand distances, and $I_o,I_7$ their improving-tile counts weighted by $u_t$. The ordinary distance includes the implementation's false-ready correction; the seven-pairs route is disabled after a meld. Let $H$ be the number of structural winning tile types, $L$ their unseen-copy total, $g$ the held white count, $p$ the current-chain piao count, and $c$ the chain length. Define

$$ f_o=\frac{8-\operatorname{clip}(d_o,0,8)+I_o/136}{9},\qquad f_7=\frac{8-\operatorname{clip}(d_7,0,8)+I_7/136}{9} $$

with $f_7=I_7=0$ for a melded hand. Let $Q$ count natural non-white quads, $J$ count non-white triplet types with unseen copies, and $P$ count natural non-white pairs (a quad counts twice). Put $b_3=\min(1,(Q+J/4)/3)$ for a closed hand and zero otherwise, $Z=\min((g+p)/4,1)$, $C=\min(c,4)/4$, and $W=H/34$. The material score is

$$ m=\max\left{\frac{f_o+Z+W+C}{4},; \frac{f_7+b_3+Z+W+C}{5};\text{if closed, else }0\right}. $$

For each hypothetical draw, $h_t$ indicates a structural wait, $e_t$ indicates a legal self-drawn win, $F_t$ is its fan, and $Y_t$ is its immediate receipt under the current dealer. Let $Y_{\min}$ be the minimum receipt over publicly possible legal winning draws. Write $v_{32}=\sum_tu_te_t\min(F_t/32,1)/U$ and $\phi(y)=\min(\log_2(1+y/10),8)/8$.

Direction Public successor preference
A1: ordinary progress $f_o$
A2: improving tiles $\max(I_o,I_7)/136$
A3: near-ready continuation $\sum_tu_t n_t/136$, where $n_t$ indicates that drawing $t$ then making an allowed discard can leave a structural wait
B1: seven-pairs progress $f_7$
B2: natural pairs $P/7$
B3: luxury-pair material $b_3$
B4: retained whites $g/4$
B5: high-fan construction $(m+v_{32})/2$ outside an active win-continuation plan; plan indicator when active
C1: live winning copies $L/U$
C2: structural wait breadth $H/34$
C3: weighted winning receipt $\sum_tu_th_t\phi(Y_t)/U$
C4: minimum winning receipt $\phi(Y_{\min})$, or zero if undefined
D1: active chain $\min(c,8)/8$
D2: piao continuation Unseen-copy fraction of next draws allowing a white discard that preserves all-type waiting and increases the chain; zero without all-type waiting or an available draw
D3: kong upgrade Active-plan action indicator, otherwise zero
D4: discard upgrade Active-plan action indicator, otherwise zero
D5: late-wall tempo $D_xL/(U\max(1,D_{\max}))$ when at most eight wall tiles remain, otherwise zero; $D_x$ is estimated own remaining draws and $D_{\max}$ is the maximum among the candidate successors

A3 is calculated only when at least one nonterminal candidate successor is within one distance step of ready; otherwise it is zero. These bounded local estimates are heuristics and do not assign probabilities to opponent responses. Terminal successor route scores are zero before plan adjustments.

An action can own several hypothetical successors, for example a meld followed by each legal discard. For direction weights $\omega_b$ and plan-adjusted score vector $\widetilde f(x)$, its scalar preference is

$$ s_a=\max_{x\in\mathcal X(a)}\omega_b^\top\widetilde f(x). $$

This is an optimistic maximum over the listed public successors, not their average and not a full game-tree value. The bounded rank transform below acts on these action-level preferences.

Finite continuation plans. At a win decision, ordinary direction scores are cleared: only active B5/D3/D4 plans may bias accepting or declining the win. A possible upgrade must have a remaining draw, at least one unseen tile type, legal wins for every publicly possible next draw, and a minimum next-win receipt strictly above the current receipt. Non-kong continuations must additionally retain structural waits on all 34 tile types. These checks concern the learner's local continuation and do not guarantee reaching the next draw before an opponent wins.

Plan Candidate continuations and priority
B5 Own kongs and eligible discards; non-white discards excluded during an active chain. Prefer the fraction of unseen draws yielding at least 32 fan, then minimum receipt, then mean receipt. At an available win, cash immediately at 32 fan or above, or if no qualifying upgrade exists
D3 Own kongs only; prefer minimum receipt, then mean receipt
D4 Non-white discards only, with no active chain; prefer minimum receipt, then mean receipt

White-discard continuations require baotou. Remaining ties use the lower action identifier. If more than one of these directions has positive weight, the planner checks B5, D3, then D4 in that order. An active plan supplies a 1/0 score for the requested plan action in its direction coordinate. Other plan-only coordinates are zero; B5 retains its material score only outside the win gate and outside a B5 plan.

The progression is decline win → execute the selected discard/kong → wait for a real draw or replacement → accept the win. It advances on actual selected actions and observed events, not on repeated queries. B5 reevaluates after arrival; D3/D4 cash at the following win gate. A deviation that invalidates the plan clears it, and game end clears all plans and direction weights. Bias changes sampling probabilities; it never forces the planned action or guarantees the projected payoff.

For candidate scalar preferences $s_a$, the rank transform is

$$ B(a)= \frac{#{a':s_a>s_{a'}}-#{a':s_a<s_{a'}}} {|\mathcal A|-1}, $$

with zero bias for a single candidate. Its magnitude is bounded by one, and ties receive the same rank score. The mechanism biases sampling rather than overriding action legality.

Every sampled decision stores its action, behavior log probability, temperature, bias vector, and bias strength. Learning holds the recorded bias and profile settings fixed while reevaluating the policy logits for the probability ratio. Deterministic evaluation uses the legal policy argmax without exploratory temperature or tactical sampling bias.

5.3 Paired return

Let $R_{gkb}$ be the learner's realized net score in branch $b$ of root $k$ in table $g$. Let $R^{\mathrm{ref}}_{gk}$ be the reference score over the same round-index window, and let $N_g$ be the table length. The branch advantage is

$$ A_{gkb}= \frac{R_{gkb}-R^{\mathrm{ref}}_{gk}}{64N_g}. $$

This single advantage is assigned to the learner's trainable decisions in that exploratory continuation. The comparison uses the same initial root and wall-seed plan, although different actions can change the realized draw and action sequence.

Here “advantage” names a realized continuation-score difference, shared by multiple decisions. It is not an unbiased estimate of the conventional state-action advantage $A^\pi(s,a)$ at every sampled decision. The divisor 64 is a numerical scaling constant, not a bound on possible Mahjong scores; $N_g$ normalizes by table horizon even though the return window is shorter.

There is no learned critic baseline in this branch objective. The value and auxiliary heads are frozen. This reduces dependence on critic calibration, but it does not eliminate variance, short-horizon bias, or stale-policy effects from sampling ahead of the learner.

5.4 Clipped objective and outcome weighting

With stored behavior probability $q_{\mathrm{old}}$,

$$ \rho_t=\frac{q_{\theta,b}(a_t\mid o_t)} {q_{\mathrm{old},b}(a_t\mid o_t)}. $$

The per-decision empirical loss uses the clipped PPO form [2], with entropy regularization on the actual sampling distribution:

$$ \ell_t= -\min!\left(\rho_t A,\operatorname{clip}(\rho_t,0.8,1.2)A\right) -\frac{\beta}{N_g}H(q_{\theta,b}(\cdot\mid o_t)), \qquad \beta=0.001. $$

For each root/branch pair, the maximum fan won by the learner in either its exploratory or reference return window determines a sample multiplier:

Maximum learner fan in either window Positive advantage Negative advantage Zero advantage
Below 8 1 1 1
8–15 5 $5/3$ 1
16–31 15 5 1
32 or higher 30 10 1

This is a training importance heuristic, not an importance correction for a naturally sampled game population. A high-fan reference win can therefore weight a negative exploratory branch even when that branch does not win.

Roots within each table are randomly divided into two disjoint halves. Each half produces one optimizer step; a root is not trained twice merely because the batch uses two steps. If table $g$ has $K_g$ roots, the implementation assigns each decision the base factor

$$ c_g=\frac{2}{100,G,\max(1,K_g),5}. $$

The half-batch loss sums $c_g W_{gkb}\ell_t$ over its decisions. There is no additional division by the number of decisions in a branch. Thus table/root normalization and decision count play different roles, and longer continuations can contribute more gradient terms.

The factor 2 compensates for using half the roots in each update, while 100 sets the overall loss scale. Together with sign-dependent, outcome-dependent $W$, this defines an empirical surrogate objective. It is not mathematically equivalent to maximizing the full-table evaluation score. In particular, $W$ reweights return outcomes, and improving a temperature-and-bias sampling policy $q$ need not improve the plain argmax deployment policy. This report makes no monotonic-improvement or unbiased-policy-gradient claim for the combination.

The branch update uses AdamW with zero weight decay, learning rate $6\times10^{-5}$, epsilon $10^{-9}$, and global gradient norm clipping at $0.001$. The two learner GPUs, when enabled, partition microbatches and reduce gradients into a single optimizer state.

5.5 Execution design

The learning process and sampling processes are separated. Samplers host frozen models and reusable inference services; the learner consumes complete branch packets. A bounded pipeline supports two batches being computed and an in-flight depth of four. Behavior versions remain attached to sampled data.

Within a root, immutable history prefixes and their inference caches can be shared across branches. The learner reconstructs the necessary raw prefix/suffix data and recomputes differentiable representations. Atomic branch-training checkpoints retain the complete model, optimizer, configuration, and run state, including the scheduling seed and round counter used to derive sampling streams. They do not capture the complete Python, NumPy, and Torch random-number-generator states; this differs from the supervised trainer's checkpoint format.

The reference experiment used two learner GPUs and two eight-GPU sampling machines. These describe the experiment's execution environment, not a minimum hardware requirement. The public entry point also supports a single learner GPU and user-specified sampler devices. No GPU instance or remote hostname is embedded in the release.

6. Evaluation protocol

6.1 Frozen plans and four-seat rotation

An evaluation fixes model identities, rule implementations, a seed, lineups, and match lengths before collecting results. Identical neural weights are deduplicated even if supplied under different names.

A group contains four rotations of a complete $N$-game table. Random streams for lineup selection, walls, and policy seeds are separate. The same table plan is reused across rotations, and each participating lineup position visits every seat. Scores and dealer transitions persist within each table.

The schedule equalizes participant seat-games and seat positions. It also improves opponent-pair balance by swapping scheduled lineup positions. Same-version copies are allowed at a table; it is not an exhaustive round-robin of every possible four-player combination.

6.2 Two score summaries

For participant $i$, let $\mu_{i,N}$ be total net score divided by its seat-game count among tables of length $N$. The official score is

$$ S_i=\sum_{N=1}^{18}w_N\mu_{i,N},\qquad w_N= \begin{cases} 0.75/7,&10\le N\le16,\\ 0.25/11,&\text{otherwise}. \end{cases} $$

Weights apply to table length, not to fan, winning hands, or a post hoc classification of games. A participant's raw cumulative score is separately reported as the unweighted sum of its actual score changes. These summaries can rank participants differently.

The 75% mass on 10–16-game tables is a preset design preference for medium-length matches while retaining coverage of shorter and longer ones. It is not an estimate of the frequency of match lengths in a measured user population, and no external calibration of the specific 75% choice is available. The plan fixed these weights before results were collected. The result therefore answers a question about this chosen utility, rather than identifying a universally strongest policy.

The evaluator requests a target participation count and rounds up to satisfy the mirrored schedule. Actual counts, rather than requested counts, are used in denominators.

6.3 Uncertainty and exact-fan counts

Bootstrap resampling is stratified by table length. The resampling unit is a complete four-seat mirrored group; games within that group are not treated as independent observations. The implementation performs 10,000 resamples and retains the original leading-pair central 50% interval.

The leading pair is selected from the observed ranking. This is an exploratory comparison, not a simultaneous confidence guarantee over all participants or an independent confirmation experiment. In particular, a 50% interval is weaker evidence than a 95% interval.

For fan $f\in{8,16,32}$, the reported rate is

$$ \operatorname{rate}_{i,f}= \frac{#{\text{participant }i\text{ wins at exactly fan }f}} {#{\text{all participant }i\text{ seat-games}}}. $$

A 64-fan win is not counted as a 32-fan win. These are observed event frequencies, not conditional opportunities under fixed hypothetical hands. Games are not divided into supposedly comparable “ordinary” and “high-fan” populations based on their eventual outcomes.

7. Final tournament results

The completed tournament contained 36 participants: 24 neural checkpoints and 12 rule policies. It comprised 23,364 complete mirrored groups, 1,081,008 games, and 120,112 seat-games per participant, with 30,028 in each seat. Its frozen plan used seed 2026101003; reproducing the original games would also require its exact participant assets and implementation identities.

7.1 Participants and scope of comparison

This is an internal pool of checkpoint and policy identities, not 36 independently developed algorithms. In the table below, v5 denotes the current model family; hof marks a retained checkpoint from an earlier selection. Numbered checkpoints are not matched-compute ablations. In particular, hof_r003400 and v5_r003400 are different weights from different training lineages.

Class Participants Interpretation and overlap with r2600 training
Current-family neural checkpoints (12) v5_hof_r001500, v5_hof_r002600, v5_hof_r002800, and v5_r002900 through v5_r003700 in steps of 100 Shared final architecture; earlier retained weights and later continuations. r1500 was an opponent in the documented final training segment. The remaining entries include the selected model and subsequent candidates, not unseen algorithms
Older neural action policies (4) router, FastHu_v8_cash, MeldNearReady_v1_cash, HighScore_v1_cash Earlier tile/history Transformer action policies, preceding the current public tactical-memory additions. Their supervised targets came from a routed behavior policy or the named rule teacher. All four were training opponents
Older RL checkpoints (8) hof_r000400, hof_r000600, hof_r000700, hof_r000800, hof_r001200, hof_r001800, hof_r002400, hof_r003400 Frozen earlier-lineage RL policies using the older representation. All were training opponents; they are not capacity- and budget-matched controls
Rule policies (12) All entries prefixed rule: below Handcrafted public-state policies with different hand-building, scoring, meld, and draw-tempo preferences. The same twelve named policy identities occurred in the training pool

The neural router participant is a direct action model trained on routed behavior, not a test-time ensemble of the twelve rules. The retained teacher-routing implementation selects a rule style at the player's first action request in a game, using the current public state and history through the game-start boundary, and keeps that style for the game. The neural model learns action outputs from routed behavior. Historical supervision records distinguish the mixed-teacher base objective, routed-action labels, and individual-teacher labels; the tournament does not isolate their respective training effects. Full ancestry and aggregate compute for every older checkpoint are not reconstructed here.

The rule pool includes speed-oriented FastHu, fan-building FanBuild/HighScore, pair-oriented PairBuild/PairKeep/PairHold, meld/near-ready policies PMH/MeldNearReady, baotou-oriented BaotouForecast, wall-tempo WallTempo, and two pre-existing hangma rule variants. These are descriptive categories, not standardized external benchmarks. The _cash wrapper checks for a same-turn kong replacement that preserves a win on every publicly possible replacement tile and strictly improves its minimum fan, then cashes the win. It retains the underlying style's other choices. A neural entry and a rule: entry sharing a name are separate participants, with potentially different actions and scores.

Only the framework and r2600 weights are released. These descriptions and aggregate results do not imply that the historical opponents are included or that their whole training provenance is publicly reproducible.

7.2 Complete ranking

The selected r2600 checkpoint ranked first by the official weighted score. All 36 results are shown; positive and negative cumulative scores use the same zero-sum settlement units as Section 2.

Official rank Participant Weighted score per seat-game Raw cumulative net score
1 v5_hof_r002600 (released r2600) +0.452171 +52,689
2 v5_hof_r002800 +0.430258 +57,203
3 v5_r003600 +0.414571 +51,128
4 v5_r003500 +0.389225 +47,700
5 v5_r003400 +0.382098 +48,621
6 v5_r003200 +0.381184 +48,189
7 v5_r002900 +0.363034 +41,464
8 v5_r003100 +0.358582 +37,955
9 v5_r003000 +0.297452 +31,558
10 v5_r003700 +0.292006 +34,934
11 router +0.270954 +26,536
12 v5_r003300 +0.241029 +32,400
13 v5_hof_r001500 +0.223769 +26,585
14 hof_r001800 +0.207616 +21,227
15 hof_r002400 +0.177267 +21,609
16 hof_r000800 +0.110475 +14,125
17 hof_r001200 +0.099221 +11,213
18 hof_r003400 +0.043996 +10,449
19 hof_r000400 +0.014125 +5,802
20 hof_r000700 +0.009974 +7,216
21 hof_r000600 −0.011407 −2,547
22 rule:hangmaV4_cash −0.153652 −19,434
23 rule:BaotouForecast_v1_cash −0.163758 −20,017
24 rule:MeldNearReady_v1_cash −0.184265 −21,139
25 MeldNearReady_v1_cash −0.201419 −21,705
26 rule:hangmaV6_cash −0.204959 −28,875
27 rule:WallTempo_v3_cash −0.230418 −37,158
28 HighScore_v1_cash −0.287093 −31,764
29 rule:FanBuild_v7_cash −0.330764 −42,630
30 rule:PairBuild_v4_cash −0.342444 −39,043
31 FastHu_v8_cash −0.354010 −46,617
32 rule:HighScore_v1_cash −0.366307 −40,194
33 rule:FastHu_v8_cash −0.444298 −49,940
34 rule:PairHold_v4_cash −0.474070 −56,684
35 rule:PMH_v2_cash −0.585699 −71,442
36 rule:PairKeep_v2_cash −0.824444 −99,414

Participant identifiers denote distinct checkpoints, not additional models bundled with this release. The comparison is a single final same-pool tournament, not a claim about a chronological training trend.

The official first-minus-second difference was +0.021913517, with the original 50% interval [−0.024367052, +0.069381479]. The leading checkpoint is selected by the predefined score; the interval does not establish that it is consistently stronger than r2800. Raw cumulative score instead favors r2800.

7.3 Table-length dependence

The original per-length score summaries give the following descriptive decomposition. Each column averages the already reported per-seat-game means equally across the listed table lengths; it is not a new tournament or bootstrap.

Participant Mean over lengths 10–16 Mean over the other 11 lengths Official score: 75% / 25%
r2600 +0.391527 +0.634105 +0.452171
r2800 +0.474713 +0.296892 +0.430258

r2600's higher overall point estimate comes from the other lengths; it is lower on the emphasized 10–16 segment. Replacing the two group weights by $\alpha$ and $1-\alpha$ would make these two point estimates equal at $\alpha\approx0.802125$, favoring r2800 above that value. This is arithmetic on existing means, not evidence of a statistically reliable difference within either length group. The official weights and ranking remain unchanged. No new interval or alternative primary result is inferred from this sensitivity calculation.

7.4 Exact-fan observations and result integrity

Selected exact-fan results are:

Participant Exact 8-fan wins Exact 16-fan wins Exact 32-fan wins
r2600 143 (0.11906%) 13 (0.01082%) 1 (0.00083%)
r2800 158 (0.13154%) 17 (0.01415%) 1 (0.00083%)
r3600 179 (0.14903%) 27 (0.02248%) 3 (0.00250%)
r3700 158 (0.13154%) 23 (0.01915%) 2 (0.00167%)

Every percentage uses 120,112 seat-games as its denominator. The r3300 and r3400 participants each recorded one 64-fan win, separately from these exact-fan counts.

All group identifiers were complete and unique; participation and seat counts matched the schedule. Re-aggregation reproduced the official ranking, with a maximum floating-point mean discrepancy of $1.67\times10^{-16}$. The aggregate net score over all participants was zero. These are result-integrity checks, not independent replications or additional evidence of playing strength.

The public package includes only r2600's neural weights and no historical opponent implementations or additional weights. Comparative evaluation requires users to supply their own compatible checkpoints. Reconstructing the original tournament would require the remaining weights, all twelve rule policies, and its original frozen plan. A new run with a different pool cannot be compared numerically to the table above as if it were the same experiment. Single-checkpoint self-play is available only as a software check; it cannot measure relative playing strength.

8. Limitations

The empirical result is a final within-pool comparison. There is no reported controlled ablation isolating the causal benefit of tactical successors, opponent memory, branch exploration, entropy, or fan weighting. Their inclusion describes the system; it is not evidence that each component independently improves strength.

The branch target covers at most two games, although the policy is conditioned on the full match horizon. It can miss longer-term effects. Pairing controls the initial state and random plan but does not make continuations identical or establish a measured reduction in estimator variance; changes in action order alter which tiles are consumed.

Rare large-fan wins remain sparse even at this scale. Their counts should not be read as stable probabilities for every hand pattern. The weighted training objective favors selected outcomes and can differ from unweighted score maximization.

The released checkpoint is selected from evaluated candidates. There is no external human evaluation, independent benchmark, or multiple-training-seed estimate reported here. The original training dataset and comparison pool are not included, so exact end-to-end reproduction of the reported weights or 36-participant tournament is outside this release.

9. Conclusion

This report specifies a public-information Transformer agent, a simulator-based paired exploration procedure, and a frozen-pool evaluation for one Hangzhou Mahjong rule set. The released r2600 checkpoint has the highest observed score under the predefined tournament weighting, without a reliable leading-pair separation in the reported interval. The implementation and one checkpoint support new experiments; component effectiveness, training efficiency relative to alternatives, and generalization beyond this pool remain open empirical questions.

Appendix A. Repository contents

This README is the sole documentation file. Supporting simulator and policy modules are direct dependencies of training and evaluation.

README.md
requirements.txt
.gitattributes
.gitignore
evaluate.py                 # CPU/CUDA mirrored tournament entry point
reinforce.py                # r2600-based branch-training entry point
bench_pool.py               # mirrored table execution and policy interface
mj/                         # simulator, fan/legality/shape logic, public features
train/                      # model, features, supervision, branch RL, inference
weights/
  r2600.pt                  # selected policy checkpoint; no optimizer or dataset

The source tree does not include historical opponent policies, experiment archives, match logs, demonstration data, service credentials, deployment adapters, or other neural checkpoints. Hand-shape and unseen-tile calculations needed by the neural features remain as pure feature functions; they do not implement a rule opponent.

Checkpoint identity:

  • Parameters: 52,005,062.
  • File size: 208,168,496 bytes.
  • File SHA-256: 6a5b4c29f830479b72b19b6e8ad4de33628b5331eb109a0fd99b026b67e9f0c2.
  • Tensor-name/value digest: 467615daae168b787edcf7b05f857efa6250da302a2d56d1efe5350cbcb4a306.
  • Contents: model configuration, parameter tensors, and public feature schema.
  • No optimizer state is bundled; a new training run initializes a new optimizer.

The tensor digest is formed by iterating sorted parameter names, hashing each UTF-8 name and then its contiguous CPU NumPy bytes. The separate file digest also covers serialization metadata.

Appendix B. Installation and use

B.1 Environment

Use Python 3.11 or 3.12. The reference environment uses PyTorch 2.8. CPU evaluation requires PyTorch, NumPy, and Numba. The distributed branch trainer requires Linux, CUDA-capable PyTorch, Triton (provided with the supported Linux CUDA PyTorch installation), and SSH access to user-configured sampler hosts.

git lfs install
git clone https://github.com/MaxwellCCC/hangzhou-mahjong.git
cd hangzhou-mahjong
git lfs pull
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

Choose a PyTorch build compatible with the intended CPU/CUDA environment. Run commands from the repository root.

The checkpoint is stored through Git LFS because it exceeds GitHub's normal single-file Git limit. Install Git LFS before cloning; in an existing checkout, run git lfs pull to fetch the checkpoint. The included .gitattributes configures weight tracking.

B.2 Self-play check and comparative evaluation

python evaluate.py \
  --device cpu \
  --self-play \
  --out runs/cpu_smoke

This runs r2600 in all four seats for a single-game table under four seat rotations: four actual games and sixteen seat-games for the same participant. Its aggregate net score is zero by construction. The report does not designate a champion or compute a pairwise confidence interval; this checks model loading and complete game execution, not strength.

A comparison against a user-supplied compatible checkpoint on a CUDA device:

python evaluate.py \
  --device cuda --devices 0 \
  --model candidate=/path/to/candidate.pt \
  --workers 4 --threads 2 \
  --seats 40000 \
  --out runs/comparison

Use --seats 120000 for three times the standard target. Repeat --model NAME=PATH to add more compatible checkpoints; comparative evaluation requires at least two distinct sets of weights, including r2600. Use --device cpu for a sequential CPU comparison. Each model seat receives its own history state. Resume an interrupted evaluation using the same arguments and output directory; a different frozen plan is rejected. Mirroring and balanced participation can round the requested seat count upward.

Outputs include plan.json, groups.jsonl, summary.json, and scores_and_fan.json. The summary records the weighted and pooled per-seat-game scores. The exact-fan report records raw cumulative scores, actual participation counts, and exact 8/16/32-fan wins. None of these generated run files belongs in the source release.

B.3 Continue branch training from the released model

Install the same source tree and dependencies on the learner and sampler hosts. Configure SSH yourself. A minimal sampler JSON, saved outside the tracked source, is:

{
  "host": "your-sampler-ssh-alias",
  "project": "/path/to/this/repository",
  "python": "/path/to/venv/bin/python",
  "devices": [0],
  "prefetch_batches": 2,
  "prefetch_depth": 4,
  "continuous_prefetch": true,
  "share_prefix": true
}

For multiple sampler machines, use a "samplers" array containing per-host overrides, with shared settings at the top level. Model files are transferred to the sampler service by the training transport. Communication uses trusted SSH-connected processes and Python serialization; this is not an unauthenticated public inference API.

python reinforce.py \
  --samplers /path/to/samplers.json \
  --out runs/branch_rl \
  --rounds 100 \
  --update-devices 0

Use --update-devices 0,1 for the two-learner-GPU path. Resume a run with the same command and --resume. The round limit is the total target for that run, not an additional-round count.

The wrapper initializes the learner and one frozen neural opponent from the same r2600 checkpoint, with no bundled rule opponents. The internal name "router" in its generated opponent manifest is a role name for that frozen checkpoint, not a separate bundled router model. Training can add newly selected checkpoints to its own run's opponent pool. This is a new self-play population and optimizer state; it does not reconstruct the original training population or resume its old optimizer.

Advanced users can invoke python -m train.ppo_v4 --help to configure the training implementation directly.

B.4 Supervised data and training

The supervised loader supports two existing table formats:

Format Layout and required information
router_action_table_v2 dir_config.json declares the schema; tables/table-*.npz stores table partitions, decision/event offsets, current observations, causal history, legal masks, action/teacher labels, and auxiliary targets
v4_tactical_warmup dir_config.json lists table files and their train/validation split; each table file contains the raw table structure plus the tactical successor and public-memory features required by a tactical checkpoint

TableDataset in train/action_inputs.py is the executable data contract. For the released tactical checkpoint, use a compatible tactical dataset with its per-decision "tactical" records; the basic NPZ loader alone does not synthesize these records.

A tactical dataset directory has a configuration such as:

{
  "schema": "v4_tactical_warmup",
  "tables": [
    {"path": "table_train.pt", "split": "train"},
    {"path": "table_validation.pt", "split": "validation"}
  ]
}

Those files must contain actual compatible table data; they are not supplied by this example. No corpus downloader or dataset-generation service is included.

python -m train.train_base_v4 \
  --data /path/to/tactical_dataset \
  --init weights/r2600.pt \
  --target router \
  --out runs/supervised \
  --lr 1e-4 \
  --epochs 7 \
  --checkpoint-layers

The initialization checkpoint defines the model architecture. Supervised continuation has separate learning-rate, auxiliary-loss, and validation settings from branch RL. It is not an automatic reproduction recipe for r2600.

References

  1. Junjie Li et al. Suphx: Mastering Mahjong with Deep Reinforcement Learning. 2020. arXiv:2003.13590.
  2. John Schulman, Filip Wolski, Prafulla Dhariwal, Alec Radford, and Oleg Klimov. Proximal Policy Optimization Algorithms. 2017. arXiv:1707.06347.
  3. Biao Zhang and Rico Sennrich. Root Mean Square Layer Normalization. 2019. arXiv:1910.07467.
  4. Jianlin Su et al. RoFormer: Enhanced Transformer with Rotary Position Embedding. 2021. arXiv:2104.09864.
  5. Noam Shazeer. GLU Variants Improve Transformer. 2020. arXiv:2002.05202.
  6. Dimitri P. Bertsekas, John N. Tsitsiklis, and Cynara Wu. Rollout Algorithms for Combinatorial Optimization. Journal of Heuristics, 3:245–262, 1997. Author-hosted paper.
  7. Andrew Y. Ng and Michael I. Jordan. PEGASUS: A Policy Search Method for Large MDPs and POMDPs. Proceedings of UAI, pp. 406–415, 2000. arXiv:1301.3878.
  8. Jakob Foerster, Gregory Farquhar, Triantafyllos Afouras, Nantas Nardelli, and Shimon Whiteson. Counterfactual Multi-Agent Policy Gradients. 2017. arXiv:1705.08926.

License

The project source code, this document, and the bundled r2600 checkpoint are provided under the MIT License. External dependencies retain their own licenses.

Copyright (c) 2026 MaxwellCCC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

Hangzhou Mahjong training and evaluation framework with public-information Transformers, paired branch reinforcement learning, and the r2600 checkpoint.

Resources

Stars

186 stars

Watchers

7 watching

Forks

Releases

Packages

Contributors

Languages