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_14 = [
...     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_14, 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.

If the number of melds in the list is less than the required number of melds for the hand, the missing melds are calculated as melds that do not overlap with the tiles in the hand. For example, if the hand consists of 123p1s, three melds are required. If only two melds are provided, such as [444p, 777s], the missing third meld is calculated as a meld that does not overlap with the tiles in the hand, such as 111z.

Parameters:
  • bingpai (list[int]) – A hand excluding melds (兵牌 a.k.a. pure hand, 純手牌).

  • fulu_mianzi_list (list[FuluMianzi | None] | 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_14 = [
...     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_14, None)
>>> print(r)
0
>>> # 123m1z (3 melds required)
>>> hand_4 = [
...     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 (3 melds)
>>> melds_3 = [
...     FuluMianzi.Shunzi(12, ClaimedTilePosition.LOW),
...     FuluMianzi.Gangzi(24),
...     FuluMianzi.Kezi(27),
...     None,
... ]
>>> r_wo_melds = calculate_replacement_number(hand_4, None)
>>> print(r_wo_melds)
1
>>> r_w_melds = calculate_replacement_number(hand_4, melds_3)
>>> print(r_w_melds)
2
>>> # 456p 7777s (2 melds)
>>> melds_2 = [
...     FuluMianzi.Shunzi(12, ClaimedTilePosition.LOW),
...     FuluMianzi.Gangzi(24),
...     None,
...     None,
... ]
>>> r_w_missing_melds = calculate_replacement_number(hand_4, 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 (八萬) cannot be used. Additionally, melded sequences (明順子) cannot be used.

If the number of melds in the list is less than the required number of melds for the hand, the missing melds are calculated as melds that do not overlap with the tiles in the hand. For example, if the hand consists of 123p1s, three melds are required. If only two melds are provided, such as [444p, 777s], the missing third meld is calculated as a meld that does not overlap with the tiles in the hand, such as 111z.

Parameters:
  • bingpai (list[int]) – A hand excluding melds. (兵牌 a.k.a. pure hand, 純手牌).

  • fulu_mianzi_list (list[FuluMianzi | None] | 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_14 = [
...     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_14, None)
>>> print(r)
0
>>> # 111m1z (3 melds required)
>>> hand_4 = [
...     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 (3 melds)
>>> melds_3 = [
...     FuluMianzi.Kezi(12),
...     FuluMianzi.Gangzi(24),
...     FuluMianzi.Kezi(27),
...     None,
... ]
>>> r_wo_melds = calculate_replacement_number(hand_4, None)
>>> print(r_wo_melds)
1
>>> r_w_melds = calculate_replacement_number(hand_4, melds_3)
>>> print(r_w_melds)
2
>>> # 444p 7777s (2 melds)
>>> melds_2 = [
...     FuluMianzi.Kezi(12),
...     FuluMianzi.Gangzi(24),
...     None,
...     None,
... ]
>>> r_w_missing_melds = calculate_replacement_number(hand_4, 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)