「mahjong」 Saviez-vous que Python a une bibliothèque appelée "** mahjong **"?
↓ Bibliothèque Python "** mahjong **" https://pypi.org/project/mahjong/
Comme son nom l'indique, cette bibliothèque est une bibliothèque ** mahjong **! (La traduction anglaise de mahjong est "mahjong")
Cette fois, j'ai résumé le contenu de l'URL ci-dessus et je l'ai effectivement utilisée!
En un mot, ce que mahjong peut faire
「Mahjong hands calculation」 En d'autres termes, vous pouvez faire un calcul manuel de mahjong.
Lisons la partie description du projet dans l'article URL!
Python2.7 and 3.5+ are supported. We support the Japanese version of mahjong only (riichi mahjong).
Si vous utilisez la dernière version de Python, il ne devrait y avoir aucun problème. Et il est écrit que seul le mahjong japonais atteint est pris en charge.
Le mahjong chinois a plus de rôles que les japonais n'atteignent le mahjong, C'est compliqué parce que Friten va bien ...
Riichi mahjong hands calculation
This library can calculate hand cost (han, fu with details, yaku, and scores) for riichi mahjong(Japanese version).
Dans cette bibliothèque, vous pouvez calculer "** translation ", " numéro de marque (y compris les détails) ", " rôle " et " score **" du mahjong de portée. C'est vrai!
Génial ... cela semble horriblement difficile à mettre en œuvre normalement ...
En outre, il semble qu'il prend également en charge les modifications de règles suivantes en option. (Simplification du contenu du tableau répertorié.)
Je suis surpris qu'il prenne en charge plusieurs options.
Compter Yakuman et Pinfu est déroutant, Si vous n'y touchez pas, vous pouvez suivre les règles de base.
The code was validated on tenhou.net phoenix replays in total on 11,120,125 hands. So, we can say that our hand calculator works the same way that tenhou.net hand calculation.
Et cette bibliothèque contient ** 11 120 125 ** mains Agari du célèbre jeu de mahjong "** Tenho **". Il semble que vous puissiez le confirmer!
Vous pouvez utiliser une bibliothèque qui peut réaliser le même calcul que Tenho gratuitement ... Dieu
Essayons diverses choses!
Tout d'abord, préparez-vous! Si Python est le dernier, il n'y a pas de problème! Comme toute autre bibliothèque
pip install mahjong
Et vous êtes prêt à partir!
Voyons si nous pouvons le calculer tout de suite!
#Calcul
from mahjong.hand_calculating.hand import HandCalculator
#Mahjong
from mahjong.tile import TilesConverter
#Rôle,Règles optionnelles
from mahjong.hand_calculating.hand_config import HandConfig, OptionalRules
#Hurler
from mahjong.meld import Meld
#Vent(Endroit&Soi)
from mahjong.constants import EAST, SOUTH, WEST, NORTH
#HandCalculator(Classe de calcul)Créer une instance de
calculator = HandCalculator()
#Pour la sortie des résultats
def print_hand_result(hand_result):
#Translitération,Nombre de marques
print(hand_result.han, hand_result.fu)
#But(Dans le cas de Tsumoagari[À gauche: objectif parental,droite:Objectif enfant],Dans le cas de Ron Agari[la gauche:Tireur concédé,droite:0])
print(hand_result.cost['main'], result.cost['additional'])
#Rôle
print(hand_result.yaku)
#Détails du nombre de marques
for fu_item in hand_result.fu_details:
print(fu_item)
print('')
Après cela, des informations telles que la forme Agari
caluculator.estimate_hand_value()
Vous pouvez le calculer en le donnant comme argument à!
L'argument de caluculator.estimate_hand_value ()
est
・ Tuiles (** Majaku 牌 forme Agari )
・ Win_tile ( tuile Agari )
・ Melds ( crissement )
・ Dora_indicators ( Dora )
-Il y a une configuration ( option **).
https://github.com/MahjongRepository/mahjong/blob/master/mahjong/hand_calculating/hand.py
** Si vous agressez avec Ron ** Joueur: enfant 3 translittération 40 points Tireur: 5200 points Rôle: Tan Yao, Sanshoku Dokou
example01_ron.py
#Forme agari(man=Mans, pin=Épingles, sou=Épées, honors=Personnage)
tiles = TilesConverter.string_to_136_array(man='234555', pin='555', sou='22555')
#Agari(Épées 5)
win_tile = TilesConverter.string_to_136_array(sou='5')[0]
#Hurler(Aucun)
melds = None
#Dora(Aucun)
dora_indicators = None
#option(Aucun)
config = None
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile, melds, dora_indicators, config)
print_hand_result(result)
Sortie de résultat
>3 40
5200 0
[Tanyao, Sanshoku Doukou]
{'fu': 30, 'reason': 'base'} #Menzenron
{'fu': 4, 'reason': 'closed_pon'} #Imprimer
{'fu': 4, 'reason': 'closed_pon'} #Imprimer
{'fu': 2, 'reason': 'open_pon'} #Demain
** Si vous agressez avec Tsumo ** Joueur: enfant 6 traductions 40 notes Parent: 6000 points, Enfant 3000 points Rôles: Menzentsumo, Tanyao, Sanankou, Sanshokudoukou
example01_tsumo.py
#Forme agari(Comme ci-dessus)
tiles = TilesConverter.string_to_136_array(man='234555', pin='555', sou='22555')
#Agari(Comme ci-dessus)
win_tile = TilesConverter.string_to_136_array(sou='5')[0]
#Hurler(Aucun)
melds = None
#Dora(Aucun)
dora_indicators = None
#option(Ajouter Tsumo,Si faux, Ron)
config = HandConfig(is_tsumo=True)
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile, melds, dora_indicators, config)
print_hand_result(result)
Résultat de sortie
>6 40
6000 3000
[Menzen Tsumo, Tanyao, San Ankou, Sanshoku Doukou]
{'fu': 20, 'reason': 'base'}
{'fu': 4, 'reason': 'closed_pon'} #Imprimer
{'fu': 4, 'reason': 'closed_pon'} #Imprimer
{'fu': 4, 'reason': 'closed_pon'} #Imprimer
{'fu': 2, 'reason': 'tsumo'} #Tsumo
La différence entre Ron et Tsumo est
C'est un argument de caluculator.estimate_hand_value ()
S'il y a ou non config = HandConfig (is_tsumo = True)
dans config
(facultatif).
Outre Tsumo
・ Atteindre → ʻis_riichi ・ Ippatsu → ʻis_ippatsu
・ Rinshan Kaihou → ʻis_rinshan ・ Chankan → ʻis_chankan
・ T-shirt haut → ʻis_haitei ・ Hotei → ʻis_houtei
・ Double portée → ʻis_daburu_riichi ・ Couler du manganèse → ʻis_nagashi_mangan
・ Tenho → ʻis_tenhou ・ Renho → ʻis_renhou
・ Chiho → ʻis_chiihou`
Existe, vous pouvez donc le définir de la même manière que ʻis_tsumo = True`.
** Lorsque le vent de champ est d'est et le vent propre est du sud ** Joueur: Enfant, Auto-vent: Sud 4 translittération 40 points Tireur: 8000 points Rôles: Reach, Yakuhai (style personnel), Dora 2
example02_south.py
#Forme agari(honors=1:est, 2:Sud, 3:Ouest, 4:Nord, 5:blanc, 6:發, 7:Pendant ~)
tiles = TilesConverter.string_to_136_array(man='677889', pin='88', sou='456', honors='222')
#Agari(Homme 8)
win_tile = TilesConverter.string_to_136_array(man='8')[0]
#Hurler(Aucun)
melds = None
#Dora(Afficher la vignette,裏Dora)
dora_indicators = [
TilesConverter.string_to_136_array(pin='7')[0],
TilesConverter.string_to_136_array(sou='9')[0],
]
#option(atteindre,Auto-vent,Style de champ)
config = HandConfig(is_riichi=True, player_wind=SOUTH, round_wind=EAST)
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>4 40
8000 0
[Riichi, Yakuhai (wind of place), Dora 2]
{'fu': 30, 'reason': 'base'} #Menzenron
{'fu': 8, 'reason': 'closed_terminal_pon'} #Empreinte de Yaochu
** Lorsque le vent de champ est d'est et le vent propre est d'est ** Joueur: Parent, Style personnel: Est 3 translittération 40 points Tireur: 7700 points Rôle: Reach, Dora 2
example02_east.py
#Forme agari(honors=1:est, 2:Sud, 3:Ouest, 4:Nord, 5:blanc, 6:發, 7:Pendant ~)
tiles = TilesConverter.string_to_136_array(man='677889', pin='88', sou='456', honors='222')
#Agari(Homme 8)
win_tile = TilesConverter.string_to_136_array(man='8')[0]
#Hurler(Aucun)
melds = None
#Dora(Afficher la vignette,裏Dora)
dora_indicators = [
TilesConverter.string_to_136_array(pin='7')[0],
TilesConverter.string_to_136_array(sou='9')[0],
]
#option(atteindre,Auto-vent,Style de champ)
config = HandConfig(is_riichi=True, player_wind=EAST, round_wind=EAST)
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>3 40
7700 0
[Riichi, Dora 2]
{'fu': 30, 'reason': 'base'} #Menzenron
{'fu': 8, 'reason': 'closed_terminal_pon'} #Empreinte de Yaochu
Dora peut être défini en décrivant la vignette d'affichage dans dora_indicators
.
Auto-style à player_wind
of config
, champ wind to round_wind
of config
Il peut être défini en spécifiant «EST» (est), «SUD» (sud), «OUEST» (ouest), «NORD» (nord).
En d'autres termes, vous pouvez définir le joueur comme parent en définissant player_wind = EAST
.
** Dans le cas de Linshan Kaihou ** Joueur: enfant 3 traductions 40 notes Parent: 2600 points, Enfant: 1300 points Rôles: Linshan Kaihou, Tan Yao, Red Dora 1
example03_rinshan.py
#Forme agari(Red Dora est 0,Ou utilisez r(Toute commande est OK), has_aka_dora=Changer en vrai)
tiles = TilesConverter.string_to_136_array(man='022246', pin='333', sou='33567', has_aka_dora=True)
#Agari(Manz 6)
win_tile = TilesConverter.string_to_136_array(man='6')[0]
#Hurler(Qi:CHI,Pong:PON,Pouvez:KAN(True:Minkan,False:Ankan),Kakan:CHANKAN,Nukidora:NUKI)
melds = [
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False),
Meld(Meld.PON, TilesConverter.string_to_136_array(pin='333')),
Meld(Meld.CHI, TilesConverter.string_to_136_array(sou='567'))
]
#Dora(Aucun)
dora_indicators = None
#option(Tsumo,Rinshan Kaihou,Ajout de la règle de Dora Tan / Red)
config = HandConfig(is_tsumo=True,is_rinshan=True, options=OptionalRules(has_open_tanyao=True, has_aka_dora=True))
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>3 40
2600 1300
[Rinshan Kaihou, Tanyao, Aka Dora 1]
{'fu': 20, 'reason': 'base'}
{'fu': 16, 'reason': 'closed_kan'} #Peut signer(Ankan)
{'fu': 2, 'reason': 'open_pon'}
{'fu': 2, 'reason': 'tsumo'}
** Pour Ron Agari ** Joueur: enfant 2 translittération 40 points Tireur: 2600 points Rôle: Tan Yao, Red Dora 1
example03_ron.py
#Forme agari(Comme ci-dessus)
tiles = TilesConverter.string_to_136_array(man='022246', pin='333', sou='33567', has_aka_dora=True)
#Agari(Comme ci-dessus)
win_tile = TilesConverter.string_to_136_array(man='6')[0]
#Hurler(Comme ci-dessus)
melds = [
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False),
Meld(Meld.PON, TilesConverter.string_to_136_array(pin='333')),
Meld(Meld.CHI, TilesConverter.string_to_136_array(sou='567'))
]
#Dora(Aucun)
dora_indicators = None
#option(Ajout de la règle de Dora Tan / Red)
config = HandConfig(options=OptionalRules(has_open_tanyao=True, has_aka_dora=True))
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>2 40
2600 0
[Tanyao, Aka Dora 1]
{'fu': 20, 'reason': 'base'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 2, 'reason': 'open_pon'}
Même si ʻis_tsumo = True` est ajouté car c'est un mangeur Il n'y a pas de Tsumo dans le rôle, et il y a un vrai Tanyao.
Si le dora rouge est inclus, N'oubliez pas de définir respectivement la forme Agari et les options!
Autres règles facultatives en plus de manger de la langue et de la dora rouge,
Il peut être défini avec HandConfig (options)
de config
.
・ Double Yakuman → has_double_yakuman (T ou F)
・ Compter Yakuman → kazoe_limit (kazoe_limit = HandConfig.KAZOE_LIMITED, HandConfig.KAZOE_SANBAIMAN, HandConfig.KAZOE_NO_LIMIT)
-Manganèse arrondi → kiriage (T ou F)
・ Pinfu → fu_for_open_pinfu (T ou F)
・ Pinfutsumo → fu_for_pinfu_tsumo (T ou F)
・ Renho → renhou_as_yakuman (T ou F)
・ Daisharin → has_daisharin (T ou F)
・ Daichikrin & Daisuulin → has_daisharin_other_suits (T ou F)
** Lorsque 13 traductions ou plus sont utilisées comme Yakuman (comptage normal Yakuman) ** Joueur: enfant 29 traduction 80 points Parent: 16000 points, Enfant: 8000 points Rôles: Linshan Kaihou, Toy Toy, San Ankou, Sankantsu, Chinitsu, Red 1, Dora 16
example04_limited.py
#Forme agari(S'il n'y a qu'un seul type de tuile, a_aka_Pas besoin de dora)
tiles = TilesConverter.string_to_136_array(man='22244455777999')
#Agari(Manz Rouge 5,Cependant, la signification est la même que 5 de Manz ordinaire)
win_tile = TilesConverter.string_to_136_array(man='5')[0]
#Hurler(Daiminkan:true,Ankan:False)
melds = [
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='7777'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='9999'), True)
]
#Dora(Seul le nombre de tuiles d'affichage)
dora_indicators = [
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='6')[0],
TilesConverter.string_to_136_array(man='8')[0],
]
#option(Règles optionnelles kazoe_limite à KAZOE_NO_Limiter,S'il y a du rouge, réglez ici)
config = HandConfig(is_tsumo=True,is_rinshan=True,options=OptionalRules(kazoe_limit=HandConfig.KAZOE_LIMITED, has_aka_dora=True))
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>29 80
16000 8000
[Rinshan Kaihou, Toitoi, San Ankou, San Kantsu, Chinitsu, Dora 16, Aka Dora 1]
{'fu': 20, 'reason': 'base'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'open_terminal_kan'}
{'fu': 4, 'reason': 'closed_pon'}
{'fu': 2, 'reason': 'pair_wait'}
{'fu': 2, 'reason': 'tsumo'}
** Lorsque 13 traductions ou plus sont effectuées en tant que Sunbaiman ** Joueur: enfant 29 traduction 80 points Parent: 12000 points, Enfant: 6000 points Rôles: Linshan Kaihou, Toy Toy, San Ankou, Sankantsu, Chinitsu, Red 1, Dora 16
example04_sanbaiman.py
#Forme agari(Comme ci-dessus)
tiles = TilesConverter.string_to_136_array(man='22244455777999')
#Agari(Comme ci-dessus)
win_tile = TilesConverter.string_to_136_array(man='5')[0]
#Hurler(Comme ci-dessus)
melds = [
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='7777'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='9999'), True)
]
#Dora(Comme ci-dessus)
dora_indicators = [
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='6')[0],
TilesConverter.string_to_136_array(man='8')[0],
]
#option(Règles optionnelles kazoe_limite à KAZOE_Vers SANBAIMAN)
config = HandConfig(is_tsumo=True,is_rinshan=True,options=OptionalRules(kazoe_limit=HandConfig.KAZOE_SANBAIMAN, has_aka_dora=True))
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>29 80
12000 6000
[Rinshan Kaihou, Toitoi, San Ankou, San Kantsu, Chinitsu, Dora 16, Aka Dora 1]
{'fu': 20, 'reason': 'base'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'open_terminal_kan'}
{'fu': 4, 'reason': 'closed_pon'}
{'fu': 2, 'reason': 'pair_wait'}
{'fu': 2, 'reason': 'tsumo'}
** Lorsque 13 traductions ou plus sont Yakuman et 26 traductions ou plus sont Double Yakuman ** Joueur: enfant 29 traduction 80 points Parent: 32000 points, Enfant: 16000 points Rôles: Linshan Kaihou, Toy Toy, San Ankou, Sankantsu, Chinitsu, Red 1, Dora 16
example04_no_limit.py
#Forme agari(Comme ci-dessus)
tiles = TilesConverter.string_to_136_array(man='22244455777999')
#Agari(Comme ci-dessus)
win_tile = TilesConverter.string_to_136_array(man='5')[0]
#Hurler(Comme ci-dessus)
melds = [
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='7777'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False),
Meld(Meld.KAN, TilesConverter.string_to_136_array(man='9999'), True)
]
#Dora(Comme ci-dessus)
dora_indicators = [
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='1')[0],
TilesConverter.string_to_136_array(man='6')[0],
TilesConverter.string_to_136_array(man='8')[0],
]
#option(Règles optionnelles kazoe_limite à KAZOE_NO_Limiter)
config = HandConfig(is_tsumo=True,is_rinshan=True,options=OptionalRules(kazoe_limit=HandConfig.KAZOE_NO_LIMIT, has_aka_dora=True))
#Calcul
result = calculator.estimate_hand_value(tiles, win_tile,melds,dora_indicators, config)
print_hand_result(result)
>29 80
32000 16000
[Rinshan Kaihou, Toitoi, San Ankou, San Kantsu, Chinitsu, Dora 16, Aka Dora 1]
{'fu': 20, 'reason': 'base'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'closed_kan'}
{'fu': 16, 'reason': 'open_terminal_kan'}
{'fu': 4, 'reason': 'closed_pon'}
{'fu': 2, 'reason': 'pair_wait'}
{'fu': 2, 'reason': 'tsumo'}
En prime, il a une forme agari comme Saki-san.
Si le chinitsu contient du dora rouge,
Has_aka_dora = True
n'est pas requis pour Tiles
(forme Agari)
Seul config
(facultatif) convient.
(Si Tiles
a has_aka_dora = True
, une erreur sera renvoyée.)
Ajoutez autant de tuiles affichées que le nombre affiché à dora_indicators
.
mahjong n'est pas qu'un calcul manuel Vous pouvez également calculer le nombre de chanten!
example04_shanten.py
#Nombre de chanten
from mahjong.shanten import Shanten
#Shanten(Classe de calcul des nombres modifiés)Créer une instance de
shanten = Shanten()
#14 tuiles main
tiles = TilesConverter.string_to_34_array(man='13569', pin='123459', sou='443')
#Calcul
result = shanten.calculate_shanten(tiles)
print(result)
#résultat
>2
Cette fois, je l'ai résumé comme un mémorandum pour moi-même. Je pense que j'ai presque compensé le manque d'explication. (Je n'ai pas essayé Nukidora ou les règles d'options spéciales, mais w)
Cette bibliothèque est irrésistible en tant qu'amateur de mahjong! (Lol) Je souhaite développer une nouvelle application de mahjong en utilisant cette bibliothèque.
Recommended Posts