python でマージャンの点数計算をしてみる (5)


とりあえず、タンキ、トイツ、コーツ、ジュンツを抽出してみたいと思う。めんどうになってきたので、ソースを貼る。

point_calc.py

data = "萬3 萬4 萬5 萬5 萬6 萬7 筒1 筒1 筒1 索3 索3 索6 索8 索7"
print(data)

data_list = data.split(' ')
print(data_list)

data_list.sort()
print(data_list)

# 一個だけ
def fetch_tanki(data_list):
    return [data_list[0], data_list[1:]]

# 対の牌
def fetch_toitsu(data_list):
    # 牌がなければ None を返す
    if len(data_list) == 0:
        return None

    toitsu = []

    pai = data_list.pop(0) # 先頭の要素を取り出す
    toitsu.append(pai)

    # 同じ牌がなければ None を返す
    if pai not in data_list:
        return None

    data_list.remove(pai)
    toitsu.append(pai)

    return [toitsu, data_list]

# 同じ牌3個
def fetch_kotsu(data_list):
    # 牌がなければ None を返す
    if len(data_list) == 0:
        return None

    kotsu = []

    pai = data_list.pop(0) # 先頭の要素を取り出す
    kotsu.append(pai) # kotsu = [pai]

    for i in range(2): # 2回ループ
        # 同じ牌がなければ None を返す
        if pai not in data_list:
            return None

        data_list.remove(pai)
        kotsu.append(pai)

    return [kotsu, data_list]

# 同種で数字が3個並ぶ
def fetch_juntsu(data_list):
    # 牌がなければ None を返す
    if len(data_list) == 0:
        return None

    juntsu = []

    pai = data_list.pop(0)
    juntsu.append(pai) # juntsu = [pai]

    for i in range(2):
        pai = next_pai(pai) # pai の数字を 1 増やした牌を返す
                            # 数字が1-9でなければ None
                            # 字牌は None とする
        if pai is None:
            return None

        if pai not in data_list:
            return None

        data_list.remove(pai)
        juntsu.append(pai)

    return [juntsu, data_list]

# pai は 種類+数字
# 字牌の時は種類のみ
def next_pai(pai):
    # 1文字だけの時は None
    if len(pai) != 2:
        return None

    num = int(pai[-1]) # 末尾の数字(文字)を数値に変換
    num += 1
    if num <= 1 or num >= 10: # num が 1 になる時は'萬0'などを入力した場合。
                              # 一応チェック。
        return None

    return pai[0]+str(num)



# deepcopy でないと data_list が書き換わる
import copy
print(fetch_tanki(copy.deepcopy(data_list)))
print(fetch_toitsu(copy.deepcopy(data_list)))
print(fetch_kotsu(copy.deepcopy(data_list)))

# ジュンツテスト用
data = "萬3 萬4 萬5 萬5 萬6 萬7 筒1 筒1 筒1 索3 索3 索6 索8 索7"
print(data)

data_list = data.split(' ')
print(data_list)

print(fetch_juntsu(copy.deepcopy(data_list)))

実行結果

萬3 萬4 萬5 萬5 萬6 萬7 筒1 筒1 筒1 索3 索3 索6 索8 索7
['萬3', '萬4', '萬5', '萬5', '萬6', '萬7', '筒1', '筒1', '筒1', '索3', '索3', '索6', '索8', '索7']
['筒1', '筒1', '筒1', '索3', '索3', '索6', '索7', '索8', '萬3', '萬4', '萬5', '萬5', '萬6', '萬7']
['筒1', ['筒1', '筒1', '索3', '索3', '索6', '索7', '索8', '萬3', '萬4', '萬5', '萬5', '萬6', '萬7']]
[['筒1', '筒1'], ['筒1', '索3', '索3', '索6', '索7', '索8', '萬3', '萬4', '萬5', '萬5', '萬6', '萬7']]
[['筒1', '筒1', '筒1'], ['索3', '索3', '索6', '索7', '索8', '萬3', '萬4', '萬5', '萬5', '萬6', '萬7']]
萬3 萬4 萬5 萬5 萬6 萬7 筒1 筒1 筒1 索3 索3 索6 索8 索7
['萬3', '萬4', '萬5', '萬5', '萬6', '萬7', '筒1', '筒1', '筒1', '索3', '索3', '索6', '索8', '索7']
[['萬3', '萬4', '萬5'], ['萬5', '萬6', '萬7', '筒1', '筒1', '筒1', '索3', '索3', '索6', '索8', '索7']]

実行結果、本来は見やすいようにすべきだろう。

タンキ、トイツ、コーツ、ジュンツのリストの後ろに、残り牌のリストを出力している。
残り牌を同じように解析すれば、牌の組み合わせを表示できるのではなかろうかと思う。
ただ、このコードの不満なところは、牌の先頭からしか切り出せないことだ。

普通はもっと考えて作るかもしれないが、私の作り方は、おおむねこのような感じだ。

また時間をみて続けたい。