NAME

Game::Mahjong::Wall - the seeded order, the deal, the front and the back

VERSION

Version 0.01

SYNOPSIS

my $wall = Game::Mahjong::Wall->new(seed => $bytes, hand => 1);
my $deal = $wall->deal(0);        # { hands => { 0 => [13 kinds], 1 => ..., 3 => ... }, dealer => 0 }
my $kind = $wall->draw;           # the front
my $back = $wall->replace;        # the back, after a kong or a flower
$wall->remaining;                 # tiles left

DESCRIPTION

A wall is the 144 tiles in a seeded order, shuffled once a hand. The distribution never calls rand: the order is a function of the seed and the hand number, so a game replays from its seed and the site can publish the seed when the game ends.

The order is the site's construction, copied

order_for is the SHA-256 word stream and rejection-sampled Fisher-Yates that every game on peer2peergames.com uses, keyed "hand:$hand:$counter": eight 32-bit words per digest, the swap index drawn past the largest multiple of the range so no position is favoured. It is a copy on purpose: each game pins fixtures to its own copy, and a shared module would let one game's change move another's deal. The key carries no game name, so a seed shared with another game gives a related stream; that is accepted because the seed is published when the game ends and never reused.

The order is a permutation of positions 1 to 144 into the set; the wall's tiles are the kinds at those positions, so a wall holds four of each suit and honour kind and one of each bonus kind.

The deal is positional and the dice are the seed

The rulebook's dice and the break in the wall (3.5.7.5) decide only where the deal starts, and the order already decides that. So the deal is the first fifty-three tiles: four at a time to the seats from the dealer counterclockwise, three rounds; then one each; then the dealer's fourteenth. The dealer's fourteenth is part of the deal and not a draw, because a draw is an event with a seat and the deal is one event.

Two ends

A draw takes the front. A replacement, after a kong or an exposed flower (3.4.20, 3.6.8), takes the back. A wall that replaced from the front would change which tile is the last of the wall, and the Last Tile fans would move with nothing red until a fixture said so.

No dead wall

The rulebook's drawn game is "the wall has been completely depleted" (3.4.30), and the Last Tile Draw fan is scored on the very last tile, so every tile is drawable and there is no reserve. Drawing from an empty wall dies: the rules ask remaining first and end the hand.

ATTRIBUTES

seed

The seed, any non-empty string; the site gives thirty-two bytes.

hand

The hand number, 1 upward, part of the stream key.

tiles

The remaining wall, front first. May be given to the constructor as a written wall for a test; it is checked against the set's counts but not required to be whole.

drawn, replaced, dealt

Counts of draws and replacements taken, and whether the deal has happened.

METHODS

order_for

my @order = Game::Mahjong::Wall::order_for($seed, $hand);

A plain function: the permutation of 1 to 144 for a seed and a hand number.

deal

my $deal = $wall->deal($dealer_seat);

Removes fifty-three tiles and returns the four hands, sorted, keyed by seat 0 to 3. Dies on a second deal.

draw

The front tile. Dies on an empty wall.

replace

The back tile. Dies on an empty wall.

remaining

How many tiles are left.

is_empty

Whether none are.

peek

A copy of the remaining tiles, for tests and for the terminal's cheat mode; the rules never call it.

DEALT

Fifty-three.

SEE ALSO

Game::Mahjong, Game::Mahjong::Tiles, Game::Mahjong::Hand

AUTHOR

LNATION <email@lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION <email@lnation.org>.

This is free software, licensed under the Artistic License 2.0.