概要
mahjong は Python 向けの麻雀ライブラリです。
点数計算・シャンテン数計算・牌姿文字列のパースなどを提供します。
v2.0.0 では点数計算の高速化や API の整理などが行われました。今回の v2.1.0 では、三人麻雀への対応を中心に、新機能の追加やバグ修正が行われました。
本記事では、v2.0.0 から v2.1.0 への主な変更点を紹介します。
筆者は v1.3.0 以降の開発に参加しており、v2.0.0 からメンテナーを務めています。
PyPI:
GitHub:
前回の記事:
v2.0.0 → v2.1.0 変更点ハイライト
三人麻雀のシャンテン数計算に対応
Shanten.calculate_shanten() と Shanten.calculate_shanten_for_regular_hand() に is_three_player 引数が追加されました。
is_three_player=True を指定すると、二萬〜八萬を使用しない三人麻雀のルールでシャンテン数を計算します。
from mahjong.shanten import Shanten
from mahjong.tile import TilesConverter
tiles = TilesConverter.one_line_string_to_34_array("1111m111122233z")
print(Shanten.calculate_shanten(tiles))
print(Shanten.calculate_shanten(tiles, is_three_player=True))
出力:
1
2
四人麻雀では一萬を順子の一部として利用できるため1シャンテンですが、三人麻雀では二萬・三萬を使用できないため2シャンテンになります。
また、is_three_player=True の場合、手牌に二萬〜八萬が含まれていると ValueError が送出されます。
三人麻雀の点数計算に対応
OptionalRules に is_three_player 引数が追加され、三人麻雀の点数計算に対応しました。
OptionalRules(is_three_player=True) を指定すると、以下のルールが適用されます。
- ツモ損あり:ツモ和了時の支払いは他家2人分のみとし、存在しない北家の支払い分は補填しません(天鳳と同様)。
- 積み棒:ツモ和了時は、積み棒1本につき他家2人が100点ずつ支払い、合計200点になります。
- ドラ表示牌:一萬がドラ表示牌の場合、九萬をドラとして扱います。裏ドラにも適用されます。
ドラ計算用の plus_dora() と build_dora_count_map() にも is_three_player 引数が追加されています。
抜きドラに対応
HandConfig に num_nuki_dora 引数が追加され、三人麻雀の抜きドラに対応しました。
抜いた北の枚数を指定すると、1枚につき1飜のドラが加算されます。
また、抜いた北は通常のドラ表示牌・裏ドラ表示牌によるドラとしても計算されます。例えばドラ表示牌が西で、立直後の裏ドラ表示牌も西の場合、抜いた北1枚につき合計3飜になります。
以下は、三人麻雀で北を1枚抜き、立直してツモ和了した場合の例です。
from mahjong.hand_calculating.hand import HandCalculator
from mahjong.hand_calculating.hand_config import HandConfig, OptionalRules
from mahjong.tile import TilesConverter
tiles = TilesConverter.one_line_string_to_136_array("99m123456789p234s")
win_tile = TilesConverter.one_line_string_to_136_array("4s")[0]
# ドラ表示牌・裏ドラ表示牌はどちらも西
dora_indicators = TilesConverter.one_line_string_to_136_array("3z")
ura_dora_indicators = TilesConverter.one_line_string_to_136_array("3z")
config = HandConfig(
is_riichi=True,
is_tsumo=True,
tsumi_number=1,
num_nuki_dora=1,
options=OptionalRules(is_three_player=True),
)
result = HandCalculator.estimate_hand_value(
tiles,
win_tile,
dora_indicators=dora_indicators,
ura_dora_indicators=ura_dora_indicators,
config=config,
)
print(result.han, result.fu)
print(result.cost["total"])
print(result.yaku)
出力:
8 20
12200
[Menzen Tsumo, Riichi, Pinfu, Ittsu, Dora 2, Ura Dora 1]
Dora 2 には抜きドラ1飜と通常のドラ1飜が含まれています(天鳳と同様)。さらに裏ドラ1飜が加算されています。
点数には三人麻雀のツモ損と、積み棒1本分の200点が反映されています。
Python 3.15 に対応
Python 3.15 が正式なサポート対象に追加されました。
また、CI のテスト対象も拡充され、以下の Python 処理系でテストが行われるようになりました。
- PyPy 3.12
- GraalPy
- free-threaded CPython
バグ修正
高点法の処理を修正
HandCalculator.estimate_hand_value() における高点法の処理を修正しました。
従来は飜数と符数に基づいて手牌の分解結果を比較していましたが、v2.1.0 では実際の得点が最大となる分解結果を選択するようになりました。
例えば、数え役満を三倍満で打ち切るルールでは、以下のようなケースで問題が発生していました。
| 手牌分解 | 飜数 | 子のロン和了点 |
|---|---|---|
| 数え役満(三倍満で打ち切り) | 14飜 | 24,000点 |
| 四暗刻 | 13飜相当 | 32,000点 |
従来は14飜の分解結果が優先され、24,000点と計算される場合がありました。
v2.1.0 では実際の得点を比較するため、32,000点となる四暗刻が選択されます。
また、得点が同じ場合は、天鳳と同様に数え役満よりも通常の役満を優先するようになりました。
HandConfig のインスタンス共有による不具合を修正
HandCalculator.estimate_hand_value() で config=None を指定した際の処理を修正しました。
従来はデフォルトの HandConfig インスタンスが共有されており、複数スレッドから利用した際にドラの計算結果が不正になる可能性がありました。
v2.1.0 では呼び出しごとに新しい HandConfig インスタンスを生成するようになり、この問題が解消されました。
移行時の注意点
v2.1.0 では、v2.0.0 の主要 API に対する破壊的変更はありません。
追加された is_three_player などの引数には従来と同じ動作となるデフォルト値が設定されているため、既存の四人麻雀向けコードは基本的にそのまま利用できます。
三人麻雀で使用する場合は、シャンテン数計算と点数計算でそれぞれ設定が必要です。
- シャンテン数計算:
is_three_player=True - 点数計算:
OptionalRules(is_three_player=True) - 抜きドラ:
HandConfig(num_nuki_dora=...)
なお、今回対応した三人麻雀の点数計算は、天鳳式のツモ損ありルールを対象としています。ツモ損なしルールには対応していません。
また、高点法の処理が修正されているため、一部の手牌では v2.0.0 と計算結果が異なる可能性があります。
まとめ
v2.1.0 では、三人麻雀のシャンテン数計算・点数計算への対応と、抜きドラのサポートが追加されました。
また、高点法の処理や HandConfig のインスタンス共有に関する不具合が修正され、Python 3.15 への対応と CI の拡充も行われました。
詳細な変更履歴については、CHANGELOG を参照してください。
CHANGELOG: https://github.com/MahjongRepository/mahjong/blob/v2.1.0/CHANGELOG.md