NAME

Game::Mahjong::Tiles - the forty-two kinds, and the set of 144

VERSION

Version 0.01

SYNOPSIS

use Game::Mahjong;

my @set = Game::Mahjong::Tiles::set();     # 144 kind ids, four of each suit
                                           # and honour kind, one of each bonus
Game::Mahjong::Tiles::code_of(19);         # "s1"
Game::Mahjong::Tiles::id_of('dg');         # 33
Game::Mahjong::Tiles::suit_of(5);          # "m"
Game::Mahjong::Tiles::rank_of(5);          # 5
Game::Mahjong::Tiles::is_terminal(9);      # 1
Game::Mahjong::Tiles::name_of(33);         # "green dragon"

DESCRIPTION

A kind is an integer from 1 to 42, and the table behind it is C (include/mahjong_abi.h, mahjong_tiles.c): the decomposer and the shanten walk that table for every candidate discard, and a second copy of it in Perl would be a second place for a flag to be wrong. This module is the Perl face of the table plus what has no business in C.

The order is part of the interface

1 to 9     m1 to m9   characters
10 to 18   p1 to p9   dots
19 to 27   s1 to s9   bamboo
28 to 31   we ws ww wn
32 to 34   dr dg dw   red, green, white
35 to 38   f1 to f4   plum, orchid, bamboo, chrysanthemum
39 to 42   t1 to t4   spring, summer, autumn, winter

Within a suit $kind + 1 is the next rank, and m9 + 1 is the one of dots and not a character. The shifted-chow and shifted-pung checks walk ids inside a suit on that promise, and next_in_suit is the walk written once.

A kind, not a tile

Four tiles of every kind 1 to 34 exist and they are identical. Nothing here names the third five of bamboo; a hand counts kinds.

A number off the table dies

code_of(0), code_of(43) and id_of('x') die with this module's sentence. An off-table kind is a programmer error, and the house rule is that programmer error dies where a refused move is returned.

FUNCTIONS

All are plain functions, not methods.

set

The 144 tiles as a list of kind ids: four of each kind 1 to 34, then one of each bonus kind 35 to 42.

kinds

The list 1 to 34.

patterns

The list 1 to 42.

code_of

The two-letter code of a kind.

id_of

The kind of a two-letter code. Dies on a code that names no kind.

suit_of

m, p or s for a suit tile; undef for an honour or a bonus tile.

rank_of

1 to 9 for a suit tile; undef otherwise.

wind_index

0 to 3 (east, south, west, north) for a wind; undef otherwise.

dragon_index

0 to 2 (red, green, white) for a dragon; undef otherwise.

bonus_index

0 to 3 for a flower or a season; undef otherwise.

flags_of

The raw flag word from the table, for tests.

is_suit, is_honour, is_wind, is_dragon, is_terminal, is_simple, is_bonus, is_flower, is_season, is_green, is_reversible

1 or 0. is_green is fan 3's set (the 2, 3, 4, 6 and 8 of bamboo and the green dragon); is_reversible is fan 40's (the 1, 2, 3, 4, 5, 8 and 9 of dots, the 2, 4, 5, 6, 8 and 9 of bamboo, and the white dragon: fourteen kinds).

name_of

The English name: "five of characters", "east wind", "red dragon", "plum". For the terminal and for the catalogue key's English only.

suit_name

The English of a suit letter.

next_in_suit

The kind one rank up in the same suit, or undef at a nine or for anything that is not a suit tile.

KINDS, BONUS, PATTERNS, PER_KIND, TILES

34, 8, 42, 4, 144. The tests check them against the table and the set rather than trusting the literals.

_abi_ptr, _abi_version, _abi_kinds

The table's address, the ABI version and the pattern count, for a downstream XS module and for the tests.

SEE ALSO

Game::Mahjong, Game::Mahjong::Notation

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.