xiangting-py documentation
Python bindings for xiangting.
See also xiangting for more information.
The hand is represented as an array of list[int], where each
element represents the count of a specific tile. The correspondence
between the index and the tile is shown in the table below.
Index |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Tile |
1m |
2m |
3m |
4m |
5m |
6m |
7m |
8m |
9m |
Index |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
Tile |
1p |
2p |
3p |
4p |
5p |
6p |
7p |
8p |
9p |
Index |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Tile |
1s |
2s |
3s |
4s |
5s |
6s |
7s |
8s |
9s |
Index |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Tile |
East (1z) |
South (2z) |
West (3z) |
North (4z) |
White (5z) |
Green (6z) |
Red (7z) |
Example
>>> # 123m456p789s11222z
>>> hand = [
... 1, 1, 1, 0, 0, 0, 0, 0, 0, # m
... 0, 0, 0, 1, 1, 1, 0, 0, 0, # p
... 0, 0, 0, 0, 0, 0, 1, 1, 1, # s
... 2, 3, 0, 0, 0, 0, 0, # z
... ]
>>> r = calculate_replacement_number(hand, None)
>>> print(r)
0
- class xiangting.ClaimedTilePosition
Position of the claimed tile in the melded sequence.
Used in
FuluMianzi.Shunzi.- LOW
The claimed tile is the lowest in the sequence. For example, claiming a 3 to form a sequence of 3-4-5.
- MIDDLE
The claimed tile is the middle in the sequence. For example, claiming a 4 to form a sequence of 3-4-5.
- HIGH
The claimed tile is the highest in the sequence. For example, claiming a 5 to form a sequence of 3-4-5.
- xiangting.calculate_replacement_number(bingpai, fulu_mianzi_list)
Calculates the replacement number (= xiangting number + 1) for a given hand.
This function is for 4-player mahjong.
In some rulesets, melded tiles are excluded when checking whether a hand contains four identical tiles. In others, melded tiles are included in the calculation. This function allows you to control that behavior via the
fulu_mianzi_listargument:Use
Noneif melds are excluded in the ruleset (e.g., Tenhou, Mahjong Soul).Provide
Sequence[FuluMianzi]if melds are included (e.g., World Riichi Championship, M.LEAGUE).
If fewer melds are provided than required for a complete hand, the missing ones are treated as melds that do not overlap with the tiles in the hand. For example, with the hand 123p1s, three melds are required. If only two are given (e.g., [444p, 777s]), the third is considered to be a non-overlapping meld, such as 111z.
- Parameters:
bingpai (list[int]) – A hand excluding melds (兵牌 a.k.a. pure hand, 純手牌).
fulu_mianzi_list (Sequence[FuluMianzi] | None) – An optional list of melds.
- Returns:
The replacement number (= xiangting number + 1).
- Return type:
int
- Raises:
ValueError – If an invalid hand (手牌) is provided.
Examples
>>> # 123m456p789s11222z >>> hand = [ ... 1, 1, 1, 0, 0, 0, 0, 0, 0, # m ... 0, 0, 0, 1, 1, 1, 0, 0, 0, # p ... 0, 0, 0, 0, 0, 0, 1, 1, 1, # s ... 2, 3, 0, 0, 0, 0, 0, # z ... ] >>> r = calculate_replacement_number(hand, None) >>> print(r) 0 >>> # 123m1z >>> hand = [ ... 1, 1, 1, 0, 0, 0, 0, 0, 0, # m ... 0, 0, 0, 0, 0, 0, 0, 0, 0, # p ... 0, 0, 0, 0, 0, 0, 0, 0, 0, # s ... 1, 0, 0, 0, 0, 0, 0, # z ... ] >>> # 456p 7777s 111z >>> melds_3 = [ ... FuluMianzi.Shunzi(12, ClaimedTilePosition.LOW), ... FuluMianzi.Gangzi(24), ... FuluMianzi.Kezi(27), ... ] >>> r_wo_melds = calculate_replacement_number(hand, None) >>> print(r_wo_melds) 1 >>> r_w_melds = calculate_replacement_number(hand, melds_3) >>> print(r_w_melds) 2 >>> # 456p 7777s >>> melds_2 = [ ... FuluMianzi.Shunzi(12, ClaimedTilePosition.LOW), ... FuluMianzi.Gangzi(24), ... ] >>> r_w_missing_melds = calculate_replacement_number(hand, melds_2) >>> print(r_w_missing_melds) 1
- xiangting.calculate_replacement_number_3_player(bingpai, fulu_mianzi_list)
Calculates the replacement number (= xiangting number + 1) for a given hand.
This function is for 3-player mahjong.
Tiles from 2m (二萬) to 8m (八萬) are not used. In addition, melded sequences (明順子) are not allowed.
In some rulesets, melded tiles are excluded when checking whether a hand contains four identical tiles. In others, melded tiles are included in the calculation. This function allows you to control that behavior via the
fulu_mianzi_listargument:Use
Noneif melds are excluded in the ruleset (e.g., Tenhou, Mahjong Soul).Provide
Sequence[FuluMianzi]if melds are included (e.g., World Riichi Championship, M.LEAGUE).
If fewer melds are provided than required for a complete hand, the missing ones are treated as melds that do not overlap with the tiles in the hand. For example, with the hand 123p1s, three melds are required. If only two are given (e.g., [444p, 777s]), the third is considered to be a non-overlapping meld, such as 111z.
- Parameters:
bingpai (list[int]) – A hand excluding melds. (兵牌 a.k.a. pure hand, 純手牌).
fulu_mianzi_list (Sequence[FuluMianzi] | None) – An optional list of melds.
- Returns:
The replacement number (= xiangting number + 1).
- Return type:
int
- Raises:
ValueError – If an invalid hand (手牌) is provided.
Examples
>>> # 111m456p789s11222z >>> hand = [ ... 3, 0, 0, 0, 0, 0, 0, 0, 0, # m ... 0, 0, 0, 1, 1, 1, 0, 0, 0, # p ... 0, 0, 0, 0, 0, 0, 1, 1, 1, # s ... 2, 3, 0, 0, 0, 0, 0, # z ... ] >>> r = calculate_replacement_number(hand, None) >>> print(r) 0 >>> # 111m1z >>> hand = [ ... 3, 0, 0, 0, 0, 0, 0, 0, 0, # m ... 0, 0, 0, 0, 0, 0, 0, 0, 0, # p ... 0, 0, 0, 0, 0, 0, 0, 0, 0, # s ... 1, 0, 0, 0, 0, 0, 0, # z ... ] >>> # 444p 7777s 111z >>> melds_3 = [ ... FuluMianzi.Kezi(12), ... FuluMianzi.Gangzi(24), ... FuluMianzi.Kezi(27), ... ] >>> r_wo_melds = calculate_replacement_number(hand, None) >>> print(r_wo_melds) 1 >>> r_w_melds = calculate_replacement_number(hand, melds_3) >>> print(r_w_melds) 2 >>> # 444p 7777s >>> melds_2 = [ ... FuluMianzi.Kezi(12), ... FuluMianzi.Gangzi(24), ... ] >>> r_w_missing_melds = calculate_replacement_number(hand, melds_2) >>> print(r_w_missing_melds) 1
- class xiangting.FuluMianzi
副露面子: Meld.
- Examples
>>> # 4-56p (Chii 4p Low) >>> shunzi = FuluMianzi.Shunzi(12, ClaimedTilePosition.LOW) >>> # 1-11z (Pon 1z) >>> kezi = FuluMianzi.Kezi(27) >>> # 7-777s (Kan 7s) >>> gangzi = FuluMianzi.Gangzi(24)
- class Gangzi(tile: int, /)
槓子: Quad.
- Parameters:
tile (int) – The index of the tile. The correspondence between the index and the tile is the same as
bingpai.
- Examples
>>> # 1-111m (Kan 1m) >>> gangzi = FuluMianzi.Gangzi(0)
- class Kezi(tile: int, /)
刻子: Triplet.
- Parameters:
tile (int) – The index of the tile. The correspondence between the index and the tile is the same as
bingpai.
- Examples
>>> # 1-11m (Pon 1m) >>> kezi = FuluMianzi.Kezi(0)
- class Shunzi(tile: int, position: ClaimedTilePosition, /)
順子: Sequence.
- Parameters:
tile (int) – The index of the tile. The correspondence between the index and the tile is the same as
bingpai.position (ClaimedTilePosition) – The position of the claimed tile in the meld. The correspondence between the index and the tile is the same as
bingpai.
- Examples
>>> # 1-23m (Chii 1m Low) >>> shunzi_low = FuluMianzi.Shunzi(0, ClaimedTilePosition.LOW) >>> # 2-13m (Chii 2m Middle) >>> shunzi_middle = FuluMianzi.Shunzi(1, ClaimedTilePosition.MIDDLE) >>> # 3-12m (Chii 3m High) >>> shunzi_high = FuluMianzi.Shunzi(2, ClaimedTilePosition.HIGH)