[Python] 180 麻雀アプリ 04 ミニ麻雀ゲーム修正

2021年3月16日作成

前回のコードに修正を入れました。

下の方の独立した関数をクラスに組み込みました。

次は他家の河を表示して鳴けるようにしようと考えています。

import random,sys
from mahjong.hand_calculating.hand import HandCalculator
from mahjong.tile import TilesConverter
from mahjong.hand_calculating.hand_config import HandConfig, OptionalRules
from mahjong.meld import Meld
from mahjong.constants import EAST, SOUTH, WEST, NORTH
from mahjong.shanten import Shanten

calculator = HandCalculator()

class Taku:
    def __init__(self):
        # 萬子:m,筒子:p,索子:s,字牌:z
        # shurui = ['m','p','s','z']
        # num = [9,9,9,7]

        # このゲームは萬子と筒子のみ
        shurui = ['m','p']
        num = [9,9]

        self.yama = []
        for s,n in zip(shurui,num):
            for i in range(1,n+1):
                hai = s + str(i)
                self.yama.append(hai)
        
        self.yama = self.yama * 4
        random.shuffle(self.yama)

class Janshi:
    def __init__(self,position):
        self.position = position
        self.tehai = []
        self.sutehai = []

    def haipai(self, yama):
        self.tehai =  yama[0:13]
        del yama[0:13]
        return self.tehai

    def ripai(self):
        self.tehai = sorted(self.tehai)
        man = [hai for hai in self.tehai if 'm' in hai]
        pin = [hai for hai in self.tehai if 'p' in hai]
        sou = [hai for hai in self.tehai if 's' in hai]
        zi = [hai for hai in self.tehai if 'z' in hai]
        self.tehai = man + pin + sou + zi

    def tsumo(self, yama):
        hai = yama[0]
        del yama[0]
        self.tehai.append(hai)
        return hai

    def dahai(self,hai):
        hai_i = self.tehai.index(hai)
        del self.tehai[hai_i]
        self.sutehai.append(hai)
        return hai

    def shanten_calc(self, tehai,position):
        tiles_man = [hai[1] for hai in self.tehai if 'm' in hai]
        tiles_pin = [hai[1] for hai in self.tehai if 'p' in hai]
        tiles_sou = [hai[1] for hai in self.tehai if 's' in hai]
        tiles_honors = [hai[1] for hai in self.tehai if 'z' in hai]

        # Shantenのインスタンス生成
        shanten = Shanten()
        tiles = TilesConverter.string_to_34_array(man=tiles_man, pin=tiles_pin, sou=tiles_sou, honors=tiles_honors)

        return str(shanten.calculate_shanten(tiles))

    def keisan(self,tehai,tsumohai,position):
        tiles_man = [hai[1] for hai in self.tehai if 'm' in hai]
        tiles_pin = [hai[1] for hai in self.tehai if 'p' in hai]
        tiles_sou = [hai[1] for hai in self.tehai if 's' in hai]
        tiles_honors = [hai[1] for hai in self.tehai if 'z' in hai]

        tsumohai_l = [tsumohai]
        print(tsumohai_l)
        end_man = [hai[1] for hai in tsumohai_l if 'm' in hai]
        end_pin = [hai[1] for hai in tsumohai_l if 'p' in hai]
        end_sou = [hai[1] for hai in tsumohai_l if 's' in hai]
        end_honors = [hai[1] for hai in tsumohai_l if 'z' in hai]

        # 和了牌姿
        tiles = TilesConverter.string_to_136_array(man=tiles_man, pin=tiles_pin, sou=tiles_sou, honors=tiles_honors)
        # 和了牌(最後のツモ牌)
        win_tile = TilesConverter.string_to_136_array(man=end_man, pin=end_pin, sou=end_sou, honors=end_honors)[0]
        # 鳴きなし
        melds = None
        # ドラなし
        dora_indicators = None
        # オプションなし
        config = None
        # 計算
        result = calculator.estimate_hand_value(tiles, win_tile, melds, dora_indicators, config)
        return result

    # 結果出力
    def print_hand_result(self,result):
        # 翻数, 符数
        print(self.result.han, self.result.fu)
        # 点数(親(放銃者),子)
        print(self.result.cost['main'], self.result.cost['additional'])
        # 役
        print(self.result.yaku)
        # 符数内容
        for fu_item in self.result.fu_details:
            print(fu_item)

taku = Taku()
yama = taku.yama
print(f'枚数 {len(yama)}')

print(f'初期状態の山\n{yama}\n')

janshi1 = Janshi('自家')
janshi1.haipai(yama)
print(f'自家手牌\n{janshi1.tehai}\n')

janshi1.ripai()
print(f'埋牌後自家手牌\n{janshi1.tehai}\n')

for i in range(18):
    position = '自家'
    print(f'{i+1}順目')
    tsumohai = janshi1.tsumo(yama)
    print(f'ツモ牌 {tsumohai}')
    janshi1.ripai()
    print(f'ツモ後手牌\n{janshi1.tehai}\n')
    print(f'向聴数 {janshi1.shanten_calc(janshi1.tehai,position)}\n')

    if int(janshi1.shanten_calc(janshi1.tehai,position)) < 0:
        janshi1.result = janshi1.keisan(janshi1.tehai,tsumohai,position)
        try:
            janshi1.print_hand_result(janshi1.result)
        except:
            print('役なしのため和了れません')
        else:
            print('和了!')
            sys.exit()

    print('捨て牌を選んでください')
    dahai = input()
    janshi1.dahai(dahai)

    print(f'打牌 {dahai}')
    print(f'打牌後手牌\n{janshi1.tehai}\n')
    print(f'捨て牌\n{janshi1.sutehai}\n')