日麻小工具
Project description
mahjong-utils-py
日麻小工具ssttkkl/mahjong-utils的Python绑定
安装
pip install mahjong-utils
使用
获取番符对应和牌点数
from mahjong_utils.point_by_han_hu import get_parent_point_by_han_hu, get_child_point_by_han_hu
# 获取亲家X番Y符的点数,返回(荣和点数, 自摸各家点数)
parent_ron, parent_tsumo = get_parent_point_by_han_hu(3, 40)
# parent_ron == 7700
# parent_tsumo == 2600
# 获取子家X番Y符的点数,返回(荣和点数, 自摸庄家点数, 自摸闲家点数)
child_ron, child_tsumo_parent, child_tsumo_child = get_child_point_by_han_hu(3, 40)
# child_ron == 5200
# child_tsumo_child == 1300
# child_tsumo_parent == 2600
手牌向听数、进张分析
from mahjong_utils.models.tile import parse_tiles
from mahjong_utils.shanten import shanten
result = shanten(parse_tiles("34568m235p68s"))
result.shanten
# 1
result.advance
# {3m, 6m, 7m, 8m, 1p, 2p, 3p, 4p, 5p, 6s, 7s, 8s}
摸牌何切分析
from mahjong_utils.models.tile import parse_tiles
from mahjong_utils.shanten import shanten
result = shanten(parse_tiles("112233p44556s127z"))
result.shanten
# 1
result.discard_to_advance
# {1p: ShantenWithoutGot(shanten=2, advance={2z, 7z, 1p, 4p, 3s, 6s, 1z}, advance_num=22, good_shape_advance=None, good_shape_advance_num=None),
# 2p: ShantenWithoutGot(shanten=2, advance={2z, 7z, 2p, 3s, 6s, 1z}, advance_num=18, good_shape_advance=None, good_shape_advance_num=None),
# 3p: ShantenWithoutGot(shanten=2, advance={2z, 7z, 3p, 3s, 6s, 1z}, advance_num=18, good_shape_advance=None, good_shape_advance_num=None),
# 4s: ShantenWithoutGot(shanten=2, advance={2z, 7z, 3s, 4s, 5s, 6s, 7s, 1z}, advance_num=24, good_shape_advance=None, good_shape_advance_num=None),
# 5s: ShantenWithoutGot(shanten=2, advance={2z, 7z, 2s, 3s, 4s, 5s, 6s, 1z}, advance_num=24, good_shape_advance=None, good_shape_advance_num=None),
# 6s: ShantenWithoutGot(shanten=1, advance={2z, 7z, 1z}, advance_num=9, good_shape_advance=set(), good_shape_advance_num=0),
# 1z: ShantenWithoutGot(shanten=1, advance={2z, 6s, 7z, 3s}, advance_num=13, good_shape_advance={2z, 7z}, good_shape_advance_num=6),
# 2z: ShantenWithoutGot(shanten=1, advance={6s, 3s, 7z, 1z}, advance_num=13, good_shape_advance={7z, 1z}, good_shape_advance_num=6),
# 7z: ShantenWithoutGot(shanten=1, advance={2z, 6s, 3s, 1z}, advance_num=13, good_shape_advance={2z, 1z}, good_shape_advance_num=6)}
鸣牌分析
from mahjong_utils.models.tile import parse_tiles, Tile
from mahjong_utils.shanten import furo_chance_shanten
result = furo_chance_shanten(parse_tiles("3456778m123457p"),
Tile.by_text("7m"))
result.shanten
# 0
result.shanten_info.chi
# {56m: ShantenWithGot(shanten=1, discard_to_advance={
# 8m: ShantenWithoutGot(shanten=1, advance={6p, 2m, 5m, 3p}, advance_num=15, good_shape_advance={6p, 2m, 5m, 3p}, good_shape_advance_num=15),
# 7p: ShantenWithoutGot(shanten=1, advance={6p, 2m, 5m, 3p}, advance_num=15, good_shape_advance={6p, 2m, 5m, 3p}, good_shape_advance_num=15),
# 4p: ShantenWithoutGot(shanten=1, advance={6p, 2m, 5m}, advance_num=12, good_shape_advance={6p}, good_shape_advance_num=4),
# 1p: ShantenWithoutGot(shanten=1, advance={6p, 2m, 5m}, advance_num=12, good_shape_advance={6p}, good_shape_advance_num=4),
# 3m: ShantenWithoutGot(shanten=2, advance={2m, 3m, 4m, 5m, 6m, 7m, 8m, 9m, 1p, 2p, 3p, 4p, 5p, 6p, 7p, 8p, 9p}, advance_num=57, good_shape_advance=None, good_shape_advance_num=None),
# 4m: ShantenWithoutGot(shanten=2, advance={1m, 2m, 3m, 4m, 5m, 6m, 7m, 8m, 9m, 1p, 2p, 3p, 4p, 5p, 6p, 7p, 8p, 9p}, advance_num=61, good_shape_advance=None, good_shape_advance_num=None),
# 7m: ShantenWithoutGot(shanten=2, advance={2m, 3m, 4m, 5m, 6m, 7m, 8m, 9m, 1p, 2p, 3p, 4p, 5p, 6p, 7p}, advance_num=49, good_shape_advance=None, good_shape_advance_num=None),
# 2p: ShantenWithoutGot(shanten=2, advance={2m, 5m, 6m, 7m, 8m, 9m, 1p, 2p, 3p, 5p, 6p, 7p, 8p, 9p}, advance_num=48, good_shape_advance=None, good_shape_advance_num=None),
# 3p: ShantenWithoutGot(shanten=2, advance={6p, 2m, 5m, 3p}, advance_num=15, good_shape_advance=None, good_shape_advance_num=None),
# 5p: ShantenWithoutGot(shanten=2, advance={2m, 5m, 6m, 7m, 8m, 9m, 1p, 2p, 3p, 4p, 5p, 6p, 7p, 8p, 9p}, advance_num=51, good_shape_advance=None, good_shape_advance_num=None)}, ankan_to_advance={}),
# 68m: ShantenWithGot(shanten=0, discard_to_advance={
# 7p: ShantenWithoutGot(shanten=0, advance={6p, 3p}, advance_num=7, good_shape_advance=None, good_shape_advance_num=None),
# 4p: ShantenWithoutGot(shanten=0, advance={6p}, advance_num=4, good_shape_advance=None, good_shape_advance_num=None),
# 1p: ShantenWithoutGot(shanten=0, advance={6p}, advance_num=4, good_shape_advance=None, good_shape_advance_num=None),
# 3m: ShantenWithoutGot(shanten=1, advance={6p, 3m, 3p, 6m}, advance_num=14, good_shape_advance={6p, 3m, 3p, 6m}, good_shape_advance_num=14),
# 4m: ShantenWithoutGot(shanten=1, advance={6p, 4m, 3p}, advance_num=10, good_shape_advance={4m}, good_shape_advance_num=3),
# 5m: ShantenWithoutGot(shanten=1, advance={6p, 2m, 5m, 3p}, advance_num=14, good_shape_advance={6p, 2m, 5m, 3p}, good_shape_advance_num=14),
# 7m: ShantenWithoutGot(shanten=1, advance={7m, 1p, 3p, 4p, 6p, 7p}, advance_num=18, good_shape_advance={6p, 7p, 7m}, good_shape_advance_num=9),
# 2p: ShantenWithoutGot(shanten=1, advance={1p, 2p, 3p, 5p, 6p, 7p, 8p, 9p}, advance_num=27, good_shape_advance={6p, 8p, 2p}, good_shape_advance_num=11),
# 3p: ShantenWithoutGot(shanten=1, advance={6p, 3p}, advance_num=7, good_shape_advance={3p}, good_shape_advance_num=3),
# 5p: ShantenWithoutGot(shanten=1, advance={1p, 2p, 3p, 4p, 5p, 6p, 7p, 8p, 9p}, advance_num=30, good_shape_advance={6p, 8p, 3p, 5p}, good_shape_advance_num=14)}, ankan_to_advance={})}
result.shanten_info.pon
# ShantenWithGot(shanten=1, discard_to_advance={
# 7p: ShantenWithoutGot(shanten=1, advance={3m, 6m, 7m, 8m, 1p, 2p, 3p, 4p, 5p, 6p}, advance_num=32, good_shape_advance={3m, 6m, 7m, 8m, 3p, 6p}, good_shape_advance_num=20),
# 4p: ShantenWithoutGot(shanten=1, advance={3m, 6m, 7m, 8m, 5p, 6p, 7p}, advance_num=23, good_shape_advance={6p}, good_shape_advance_num=4),
# 5p: ShantenWithoutGot(shanten=1, advance={7p, 1p, 4p, 7m}, advance_num=13, good_shape_advance={7m}, good_shape_advance_num=4),
# 6m: ShantenWithoutGot(shanten=1, advance={8m, 1p, 3p, 4p, 6p, 7p}, advance_num=19, good_shape_advance={6p, 7p, 8m}, good_shape_advance_num=10),
# 8m: ShantenWithoutGot(shanten=1, advance={3m, 6m, 1p, 3p, 4p, 6p, 7p}, advance_num=22, good_shape_advance={3m, 6m, 3p, 6p, 7p}, good_shape_advance_num=16),
# 1p: ShantenWithoutGot(shanten=1, advance={3m, 6m, 7m, 8m, 2p, 5p, 6p, 7p}, advance_num=26, good_shape_advance={6p, 7m}, good_shape_advance_num=8),
# 2p: ShantenWithoutGot(shanten=1, advance={7p, 1p, 7m}, advance_num=10, good_shape_advance=set(), good_shape_advance_num=0),
# 3m: ShantenWithoutGot(shanten=1, advance={8m, 1p, 3p, 4p, 6p, 7p}, advance_num=19, good_shape_advance={6p, 8m, 7p}, good_shape_advance_num=10),
# 4m: ShantenWithoutGot(shanten=2, advance={3m, 4m, 5m, 6m, 7m, 8m, 1p, 2p, 3p, 4p, 5p, 6p, 7p}, advance_num=41, good_shape_advance=None, good_shape_advance_num=None),
# 5m: ShantenWithoutGot(shanten=2, advance={2m, 3m, 4m, 5m, 6m, 7m, 8m, 1p, 2p, 3p, 4p, 5p, 6p, 7p}, advance_num=45, good_shape_advance=None, good_shape_advance_num=None),
# 3p: ShantenWithoutGot(shanten=2, advance={3m, 6m, 7m, 8m, 1p, 2p, 3p, 4p, 5p, 6p, 7p}, advance_num=35, good_shape_advance=None, good_shape_advance_num=None)}, ankan_to_advance={})
result.shanten_info.pass_
# ShantenWithoutGot(shanten=1, advance={7m, 1p, 3p, 4p, 6p, 7p}, advance_num=18, good_shape_advance={6p, 7p, 7m}, good_shape_advance_num=9)
result.shanten_info.minkan
# None
和了分析
from mahjong_utils.hora import build_hora
from mahjong_utils.models.tile import parse_tiles, Tile
from mahjong_utils.models.wind import Wind
from mahjong_utils.models.furo import Furo
from mahjong_utils.yaku.common import self_wind, round_wind
# 和了分析
hora = build_hora(
tiles=parse_tiles("12233466m111z"),
furo=[Furo.parse("789p")],
agari=Tile.by_text("1z"),
tsumo=True,
dora=4,
self_wind=Wind.east,
round_wind=Wind.east
)
# hora.yaku == {self_wind, round_wind}
# hora.han == 6
# hora.hu == 30
# hora.parent_point == (18000, 6000)
# hora.child_point == (12000, 6000, 3000)
指定绑定方式
默认情况下,py版本内部通过py-mini-racer调用mahjong-utils-entry的Kotlin/JS产物,其计算耗时约为JVM产物的2.1倍。
(为什么不是Kotlin/Native产物,因为实测下来Native产物的计算耗时约为JVM产物的7.6倍)
如果希望能够达到JVM产物的计算速度,可以选择切换绑定方式为调用mahjong-utils-webapi提供的HTTP接口,具体步骤如下:
- 确保已经安装Java (>= 11)
- 从Release页下载与python库版本相对应的mahjong-utils-webapi-all.jar
- 运行命令
java -jar mahjong-utils-webapi-all.jar(默认占用8080端口,如果需要指定端口:PORT=10021 java -jar mahjong-utils-webapi-all.jar) - 启动python解释器前设置环境变量
ENV_MAHJONG_UTILS_BRIDGE=http(如果需要指定端口与地址:ENV_MAHJONG_UTILS_HTTP_PORT=10021;ENV_MAHJONG_UTILS_HTTP_HOST=127.0.0.1)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mahjong_utils-0.7.7.tar.gz.
File metadata
- Download URL: mahjong_utils-0.7.7.tar.gz
- Upload date:
- Size: 203.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ba9e2353335b62fed631e478d8280ce55a3fa9bc303f06107411aa5eec637c5
|
|
| MD5 |
2c5fc214c476972e0f3679ebf050b1b1
|
|
| BLAKE2b-256 |
544947b26c351f3e4e26a68b2753444f5779756b8db73a462d8e781b04d3fba4
|
Provenance
The following attestation bundles were made for mahjong_utils-0.7.7.tar.gz:
Publisher:
python-package.yml on ssttkkl/mahjong-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mahjong_utils-0.7.7.tar.gz -
Subject digest:
9ba9e2353335b62fed631e478d8280ce55a3fa9bc303f06107411aa5eec637c5 - Sigstore transparency entry: 174923025
- Sigstore integration time:
-
Permalink:
ssttkkl/mahjong-utils@1ab2dfe6487e1a445934ef11b8604f09142cac58 -
Branch / Tag:
refs/tags/v0.7.7 - Owner: https://github.com/ssttkkl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@1ab2dfe6487e1a445934ef11b8604f09142cac58 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mahjong_utils-0.7.7-py3-none-any.whl.
File metadata
- Download URL: mahjong_utils-0.7.7-py3-none-any.whl
- Upload date:
- Size: 266.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4be180c7335d07e97f6336b3ceaafdf1226d7280d218342c38a44568c5f812d2
|
|
| MD5 |
1103c7876a541af806f84506b5fbd0a2
|
|
| BLAKE2b-256 |
fbc507c8d11dc32db7fb75709769f4f0d4126d31bdc7cf5ec80ae24b1d1fad49
|
Provenance
The following attestation bundles were made for mahjong_utils-0.7.7-py3-none-any.whl:
Publisher:
python-package.yml on ssttkkl/mahjong-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mahjong_utils-0.7.7-py3-none-any.whl -
Subject digest:
4be180c7335d07e97f6336b3ceaafdf1226d7280d218342c38a44568c5f812d2 - Sigstore transparency entry: 174923028
- Sigstore integration time:
-
Permalink:
ssttkkl/mahjong-utils@1ab2dfe6487e1a445934ef11b8604f09142cac58 -
Branch / Tag:
refs/tags/v0.7.7 - Owner: https://github.com/ssttkkl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@1ab2dfe6487e1a445934ef11b8604f09142cac58 -
Trigger Event:
release
-
Statement type: