mahjong.hand_calculating.fu

class mahjong.hand_calculating.fu.FuDetail[source]

Bases: TypedDict

A single fu component with its point value and reason.

Each entry in the fu breakdown returned by FuCalculator.calculate_fu() describes one source of fu (e.g., base fu, a closed pon, or a wait type).

Parameters:
  • fu – fu points awarded for this component

  • reason – identifier string matching one of the FuCalculator reason constants

class mahjong.hand_calculating.fu.FuCalculator[source]

Bases: object

Calculate fu (minipoints) for a winning hand decomposition.

Fu are computed from the hand’s meld structure, wait type, pair, and winning method. The result is a detailed breakdown of fu components and the total fu rounded up to the nearest 10.

BASE = 'base'

Base fu: 20 for open/tsumo, 30 for closed ron, 25 for chiitoitsu.

PENCHAN = 'penchan'

Penchan (edge wait): 2 fu for completing 1-2-3 with the 3, or 7-8-9 with the 7.

KANCHAN = 'kanchan'

Kanchan (closed wait): 2 fu for waiting on the middle tile of a sequence.

VALUED_PAIR = 'valued_pair'

Valued pair: 2 fu for a pair of dragon, seat wind, or round wind tiles.

DOUBLE_VALUED_PAIR = 'double_valued_pair'

Double valued pair: 4 fu when the pair tile is both seat wind and round wind.

PAIR_WAIT = 'pair_wait'

Pair wait: 2 fu for winning on the pair tile.

TSUMO = 'tsumo'

Tsumo: 2 fu for winning by self-draw.

HAND_WITHOUT_FU = 'hand_without_fu'

Open pinfu: 2 fu for an open hand with no other fu sources.

CLOSED_PON = 'closed_pon'

Closed pon of simple tiles: 4 fu.

OPEN_PON = 'open_pon'

Open pon of simple tiles: 2 fu.

CLOSED_TERMINAL_PON = 'closed_terminal_pon'

Closed pon of terminal or honor tiles: 8 fu.

OPEN_TERMINAL_PON = 'open_terminal_pon'

Open pon of terminal or honor tiles: 4 fu.

CLOSED_KAN = 'closed_kan'

Closed kan of simple tiles: 16 fu.

OPEN_KAN = 'open_kan'

Open kan of simple tiles: 8 fu.

CLOSED_TERMINAL_KAN = 'closed_terminal_kan'

Closed kan of terminal or honor tiles: 32 fu.

OPEN_TERMINAL_KAN = 'open_terminal_kan'

Open kan of terminal or honor tiles: 16 fu.

static calculate_fu(hand, win_tile, win_group, config, valued_tiles=None, melds=None)[source]

Calculate fu for a winning hand decomposition.

Analyze the hand’s meld structure, wait type, pair, and winning method to produce a detailed breakdown of fu components and the total fu rounded up to the nearest 10.

Chiitoitsu (seven pairs) always receives 25 fu:

>>> from mahjong.hand_calculating.fu import FuCalculator
>>> from mahjong.hand_calculating.hand_config import HandConfig
>>> hand = [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6]]
>>> win_tile = 24
>>> win_group = [6, 6]
>>> fu_details, fu = FuCalculator.calculate_fu(hand, win_tile, win_group, HandConfig())
>>> fu
25

A closed ron hand with only chi melds and a non-valued pair (pinfu) receives 30 fu:

>>> hand = [[0, 1, 2], [3, 4, 5], [9, 10, 11], [18, 19, 20], [27, 27]]
>>> win_tile = 20
>>> win_group = [3, 4, 5]
>>> fu_details, fu = FuCalculator.calculate_fu(hand, win_tile, win_group, HandConfig())
>>> fu
30

A closed pon of simple tiles adds 4 fu:

>>> hand = [[2, 2, 2], [3, 4, 5], [9, 10, 11], [18, 19, 20], [27, 27]]
>>> win_tile = 20
>>> win_group = [3, 4, 5]
>>> fu_details, fu = FuCalculator.calculate_fu(hand, win_tile, win_group, HandConfig())
>>> fu
40
>>> {"fu": 4, "reason": FuCalculator.CLOSED_PON} in fu_details
True

A double valued pair with an open terminal pon:

>>> from mahjong.meld import Meld
>>> hand = [[2, 3, 4], [9, 10, 11], [18, 19, 20], [33, 33, 33], [27, 27]]
>>> win_tile = 8
>>> win_group = [2, 3, 4]
>>> valued_tiles = [27, 27]
>>> melds = [Meld(meld_type=Meld.PON, tiles=[132, 133, 134], opened=True)]
>>> fu_details, fu = FuCalculator.calculate_fu(hand, win_tile, win_group, HandConfig(), valued_tiles, melds)
>>> fu
30
>>> {"fu": 4, "reason": FuCalculator.DOUBLE_VALUED_PAIR} in fu_details
True
>>> {"fu": 4, "reason": FuCalculator.OPEN_TERMINAL_PON} in fu_details
True
Parameters:
  • hand (Collection[Sequence[int]]) – decomposed hand as a collection of tile sets, each a sequence of tile indices in 34-format: a pair (length 2), chi (length 3 with consecutive tiles), pon (length 3 with identical tiles), or kan (length 4); chiitoitsu hands have 7 pairs

  • win_tile (int) – the winning tile index in 136-format

  • win_group (Sequence[int]) – the tile set (from hand) that contains the winning tile, as tile indices in 34-format

  • config (HandConfig) – hand configuration with win method and optional rule settings

  • valued_tiles (Sequence[int | None] | None) – tile indices in 34-format for tiles that grant pair fu (dragons, seat wind, round wind); pass the same index twice for double-valued

  • melds (Collection[Meld] | None) – declared melds (chi, pon, kan)

Returns:

tuple of (fu component list, total fu rounded up to nearest 10)

Return type:

tuple[list[FuDetail], int]