def pon_convert(janshi, hai_str, teban, akadora_flag):
    janshi.tsumohai_list.append(hai_str + "ポン")
    janshi.fuuro_akadora_list.append(akadora_flag)
    temp_tehai = function.tehai_convert(janshi.tehai)
    hai_index = function.hai_convert(function.akadora_hai_convert(hai_str))
    temp_tehai[hai_index] -= 2
    janshi.tehai = function.tehai_convert_reverse(temp_tehai)
    return [2, hai_index, teban]
Example #2
0
    def daiminkan_add(self, taku, hai_arr, last_dahai, teban):
        last_hai_str = function_tenhou.hai_convert_136_to_str(last_dahai)
        last_hai_index = function.hai_convert(
            function.akadora_hai_convert(last_hai_str))

        #手牌から削除
        for i in range(3):
            if hai_arr[i] in self.tehai_136:
                self.tehai_136.remove(hai_arr[i])
                self.tehai.remove(
                    function_tenhou.hai_convert_136_to_str(hai_arr[i]))

        #副露リストに追加
        self.fuurohai.append([3, last_hai_index, teban])
        if last_hai_index % 10 == 5 and last_hai_index < 30:
            self.fuuro_akadora_list.append(True)
        else:
            self.fuuro_akadora_list.append(False)
def chii_convert(janshi, hai_str, chii_index, akadora_flag):
    janshi.tsumohai_list.append(hai_str + "チー")
    janshi.fuuro_akadora_list.append(akadora_flag)
    temp_tehai = function.tehai_convert(janshi.tehai)
    hai_index = function.hai_convert(function.akadora_hai_convert(hai_str))

    if chii_index == 0:
        temp_tehai[hai_index - 2] -= 1
        temp_tehai[hai_index - 1] -= 1
        janshi.tehai = function.tehai_convert_reverse(temp_tehai)
        return [1, hai_index, chii_index]
    elif chii_index == 1:
        temp_tehai[hai_index - 1] -= 1
        temp_tehai[hai_index + 1] -= 1
        janshi.tehai = function.tehai_convert_reverse(temp_tehai)
        return [1, hai_index, chii_index]
    elif chii_index == 2:
        temp_tehai[hai_index + 1] -= 1
        temp_tehai[hai_index + 2] -= 1
        janshi.tehai = function.tehai_convert_reverse(temp_tehai)
        return [1, hai_index, chii_index]
Example #4
0
    def chii_add(self, taku, hai_arr, last_dahai):
        last_hai = function_tenhou.hai_convert_136_to_str(last_dahai)
        #tehaiとtehai_136の操作。tehai_136の中にhai_arrのIDがあれば削除
        #print(hai_arr)
        #print(self.tehai_136)

        for i in range(3):
            if hai_arr[i] in self.tehai_136:
                self.tehai_136.remove(hai_arr[i])
                self.tehai.remove(
                    function_tenhou.hai_convert_136_to_str(hai_arr[i]))

        #print(self.tehai_136)
        #print(self.tehai)

        #副露リストへの追加
        last_hai_index = function.hai_convert(
            function.akadora_hai_convert(last_hai))
        temp = function.akadora_convert(
            function_tenhou.tehai_convert_136_to_str(hai_arr))
        #print(temp)
        temp_arr_str = temp[0]
        #print(temp_arr_str)
        akadora_flag = temp[1]  #枚数
        hai_arr_index = sorted(function.tehai_convert2(temp_arr_str))
        #print(hai_arr_index)
        #print(last_hai_index)
        if hai_arr_index[0] == last_hai_index:
            self.fuurohai.append([1, last_hai_index, 2])
        elif hai_arr_index[1] == last_hai_index:
            self.fuurohai.append([1, last_hai_index, 1])
        else:  #hai_arr_index[2] == last_hai_index:
            self.fuurohai.append([1, last_hai_index, 0])
        if akadora_flag:
            self.fuuro_akadora_list.append(True)
        else:
            self.fuuro_akadora_list.append(False)
Example #5
0
def eval_defense(janshi, taku, shanten_suu, temp_max, pure_point_list,
                 bakyou_list):
    janshi_list = copy.deepcopy(janshi)
    janshi_p = janshi_list[0]
    nokori_tsumo_kaisuu = int(taku.yama_nokori / 4)

    vertual_yama = janshi_p.vertual_yama
    vertual_yama_index = function.tehai_convert(vertual_yama)
    tehai_len = len(janshi_p.tehai)
    eval_defense_point = np.zeros(tehai_len)

    for i in range(1, 4):
        #とりあえず立直者だけ警戒
        if janshi_list[i].riichi:
            tenpai_prob = 3.0
        elif janshi_list[i].fuurosuu != 0:
            tenpai_prob = janshi_list[i].fuurosuu * 0.1 * math.exp(
                ((17 - nokori_tsumo_kaisuu) / 17 - 1) * math.sqrt(5))
        else:
            continue

        #打点期待値を設定
        if janshi_list[i].kaze == 0:
            daten_expect = 10000
        else:
            daten_expect = 7000

        #max_pointの設定
        #オーラスで最下位なら防御をほとんどしない
        if bakyou_list[0] == 4:
            max_point = temp_max * 0.1
        else:
            max_point = temp_max
        #3シャンテン以上は倍
        #if shanten_suu >= 3:
        #    max_point *= 1.0
        genbutsu_list = function.akadora_convert(
            janshi_list[i].sutehai)[0] + function.akadora_convert(
                janshi_list[i].temp_genbutsu)[0]

        #危険牌枚数を計上
        temp_list = [
            "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m", "1p", "2p",
            "3p", "4p", "5p", "6p", "7p", "8p", "9p", "1s", "2s", "3s", "4s",
            "5s", "6s", "7s", "8s", "9s", "1z", "2z", "3z", "4z", "5z", "6z",
            "7z"
        ]
        for j in range(len(genbutsu_list)):
            if genbutsu_list[j] in temp_list:
                temp_list.remove(genbutsu_list[j])
        kikenhai_maisuu = len(temp_list)

        #save_max_point = max_point

        #手出しリスト作成
        tedashi_list = []
        for j in range(len(janshi_list[i].sutehai)):
            if janshi_list[i].tedashi_flag:
                tedashi_list.append(janshi_list[i].sutehai[j])

        ############メイン#########################
        max_pure = max(pure_point_list)
        yuuido = max(
            (max_pure / (daten_expect * tenpai_prob / kikenhai_maisuu))**0.5,
            0.66)
        print(yuuido)
        max_point /= yuuido

        for j in range(tehai_len):

            hai_index = function.hai_convert(janshi_p.tehai[j])

            #現物ならmax_point与えてcontinue
            temp_hai_str = function.akadora_hai_convert(janshi_p.tehai[j])
            if temp_hai_str in genbutsu_list:
                eval_defense_point[j] += max_point
                continue

            #字牌
            if hai_index > 30:
                if vertual_yama_index[hai_index] == 0:
                    eval_defense_point[j] += max_point
                    continue
                elif vertual_yama_index[hai_index] == 1:
                    eval_defense_point[j] += max_point * 0.8
                    continue
                elif vertual_yama_index[hai_index] == 2:
                    eval_defense_point[j] += max_point * 0.5
                    continue
                elif vertual_yama_index[hai_index] == 3:
                    eval_defense_point[j] += max_point * 0.2
                    continue

            #牌の種類によって減点
            if hai_index < 30:
                if hai_index % 10 == 1 or hai_index % 10 == 9:
                    eval_defense_point[j] -= max_point * 0.1
                elif hai_index % 10 == 2 or hai_index % 10 == 2:
                    eval_defense_point[j] -= max_point * 0.2
                elif hai_index % 10 == 3 or hai_index % 10 == 4 or hai_index % 10 == 5 or hai_index % 10 == 6 or hai_index % 10 == 7:
                    eval_defense_point[j] -= max_point * 0.3
                #赤ドラ
                else:
                    eval_defense_point[j] -= max_point * 0.5

            #筋牌ならば加点。宣言牌の筋は知らん
            if suji_hantei(genbutsu_list, hai_index):
                eval_defense_point[j] += max_point * 0.5

            #最終手出しおよびその一つ前の手出しのマタギならば減点。マタギは赤ドラを考えない。
            matagi_list = matagi_henkan(hai_index)
            if len(tedashi_list) >= 1:
                if function.hai_convert(tedashi_list[-1]) in matagi_list:
                    eval_defense_point[j] -= max_point * 0.5
            if len(tedashi_list) >= 2:
                if function.hai_convert(tedashi_list[-2]) in matagi_list:
                    eval_defense_point[j] -= max_point * 0.5

            #裏筋ならば減点
            urasuji_list = urasuji_henkan(hai_index)
            sutehai_index_list = function.akadora_convert3(
                function.tehai_convert3(tedashi_list))[0]
            for k in range(len(urasuji_list)):
                if urasuji_list[k] in sutehai_index_list:
                    eval_defense_point[j] -= max_point * 0.4

            #序盤に切れた数牌の外側に対して加点
            sutehai_len = len(janshi_list[i].sutehai)
            if sutehai_len > 6:
                sotohai_list = sotohai_find(janshi_list[i].sutehai,
                                            min(int(sutehai_len / 3), 4))
                if hai_index in sotohai_list:
                    eval_defense_point[j] += max_point * 0.5

            #カベの外側に対して加点
            eval_defense_point[j] += max_point * kabe_eval(
                vertual_yama_index, hai_index)

            #max_pointに補正
            if abs(eval_defense_point[j]) > max_point:
                eval_defense_point[j] *= max_point / abs(eval_defense_point[j])

    return eval_defense_point
Example #6
0
    def naki(self, m, last_dahai, last_teban):
        naki_info = decode_m(m)
        self.fuurosu += 1
        self.tsumoHai = -1  #自摸切りかどうかの確認。鳴きなのでリセット。
        #アンカン
        if naki_info[0] == 4:
            #[1][0]だと赤ドラになる可能性があるため[1][1]
            self.ankan_list.append(convert_mjlog_to_index(naki_info[1][1]))
            for h in naki_info[1]:
                if h in self.tehai:
                    self.tehai.remove(h)

        #チー
        elif naki_info[0] == 3:
            hai_arr = naki_info[1]
            #tehaiから鳴きに使った牌の削除
            for h in naki_info[1]:
                if h in self.tehai:
                    self.tehai.remove(h)

            #副露リストへの追加
            last_hai_index = convert_mjlog_to_index(int(last_dahai))
            temp = function.akadora_convert(
                function_tenhou.tehai_convert_136_to_str(hai_arr))
            temp_arr_str = temp[0]
            akadora_flag = temp[1]
            hai_arr_index = sorted(function.tehai_convert2(temp_arr_str))
            if hai_arr_index[0] == last_hai_index:
                self.fuurohai.append([1, last_hai_index, 2])
            elif hai_arr_index[1] == last_hai_index:
                self.fuurohai.append([1, last_hai_index, 1])
            else:  #hai_arr_index[2] == last_hai_index:
                self.fuurohai.append([1, last_hai_index, 0])
            if akadora_flag:
                self.fuuro_akadora_list.append(True)
            else:
                self.fuuro_akadora_list.append(False)

        #ポン
        elif naki_info[0] == 1:
            hai_arr = naki_info[1]
            teban = last_teban
            #tehaiの操作
            for h in naki_info[1]:
                if h in self.tehai:
                    self.tehai.remove(h)

            #副露リストへの追加
            #先頭が赤ドラ
            if hai_arr[0] == 16 or hai_arr[0] == 52 or hai_arr[0] == 88:
                hai_str = function_tenhou.hai_convert_136_to_str(hai_arr[1])
                hai_index = function.hai_convert(hai_str)
                self.fuurohai.append([2, hai_index, teban])
                self.fuuro_akadora_list.append(True)
            #真ん中が赤ドラ
            elif hai_arr[1] == 16 or hai_arr[1] == 52 or hai_arr[1] == 88:
                hai_str = function_tenhou.hai_convert_136_to_str(hai_arr[2])
                hai_index = function.hai_convert(hai_str)
                self.fuurohai.append([2, hai_index, teban])
                self.fuuro_akadora_list.append(True)
            #最後が赤ドラ
            elif hai_arr[2] == 16 or hai_arr[2] == 52 or hai_arr[2] == 88:
                hai_str = function_tenhou.hai_convert_136_to_str(hai_arr[0])
                hai_index = function.hai_convert(hai_str)
                self.fuurohai.append([2, hai_index, teban])
                self.fuuro_akadora_list.append(True)
            #赤ドラなし
            else:
                hai_str = function_tenhou.hai_convert_136_to_str(hai_arr[0])
                hai_index = function.hai_convert(hai_str)
                self.fuurohai.append([2, hai_index, teban])
                self.fuuro_akadora_list.append(True)

        #ダイミンカン
        elif naki_info[0] == 2:
            hai_arr = naki_info[1]
            teban = last_teban
            last_hai_str = function_tenhou.hai_convert_136_to_str(
                int(last_dahai))
            last_hai_index = function.hai_convert(
                function.akadora_hai_convert(last_hai_str))

            #手牌から削除
            for h in naki_info[1]:
                if h in self.tehai:
                    self.tehai.remove(h)

            #副露リストに追加
            self.fuurohai.append([3, last_hai_index, teban])
            if last_hai_index % 10 == 5 and last_hai_index < 30:
                self.fuuro_akadora_list.append(True)
            else:
                self.fuuro_akadora_list.append(False)

        #カカン
        elif naki_info[0] == 5:
            hai_arr = naki_info[1]
            #元からソートされているはず
            #カカンした牌の種類(hai_arr[1]としているので赤の可能性なし)
            kakan_index = function.hai_convert(
                function_tenhou.hai_convert_136_to_str(hai_arr[1]))
            #実際に加えられた牌のID(赤の可能性あり)
            temp_arr = hai_arr.copy()
            kakan_hai_id = 6 + temp_arr[0] - (
                temp_arr[0] % 4) * 2 - temp_arr[1] % 4 - temp_arr[2] % 4

            #remove
            self.tehai.remove(kakan_hai_id)

            #副露リスト更新
            for i in range(len(self.fuurohai)):
                if self.fuurohai[i][1] == kakan_index and self.fuurohai[i][
                        0] == 2:
                    self.fuurohai[i][0] = 3
                    #kakan_indexが5,15,25なら赤ドラあり
                    if kakan_index % 10 == 5 and kakan_index < 30:
                        self.fuuro_akadora_list[i] = True
Example #7
0
def create_danger_degree_list(janshi, taku, bakyou_list):
    danger_degree_list = [0] * 38
    danger_degree_list_return = [1.0] * 38
    #オーラスで最下位ならぜんぶ1.0
    if bakyou_list[0] == 4:
        return danger_degree_list_return

    janshi_list = copy.deepcopy(janshi)
    janshi_p = janshi_list[0]
    nokori_tsumo_kaisuu = int(taku.yama_nokori / 4)

    vertual_yama = janshi_p.vertual_yama
    vertual_yama_index = function.tehai_convert(vertual_yama)

    for i in range(1, 4):
        #とりあえず立直者だけ警戒
        if janshi_list[i].riichi:
            tenpai_prob = 1.0
        elif janshi_list[i].fuurosuu != 0:
            tenpai_prob = janshi_list[i].fuurosuu * 0.09 * math.exp(
                ((17 - nokori_tsumo_kaisuu) / 17 - 1) * math.sqrt(5))
        else:
            continue

        #max_pointの設定
        genbutsu_list = function.akadora_convert(
            janshi_list[i].sutehai)[0] + function.akadora_convert(
                janshi_list[i].temp_genbutsu)[0]

        #手出しリスト作成
        tedashi_list = []
        for j in range(len(janshi_list[i].sutehai)):
            if janshi_list[i].tedashi_flag:
                tedashi_list.append(janshi_list[i].sutehai[j])

        ############メイン#########################
        temp_list = list(range(len(danger_degree_list)))
        temp_list.remove(0)
        temp_list.remove(10)
        temp_list.remove(20)
        temp_list.remove(30)
        for j in temp_list:
            hai_index = j
            #現物ならcontinue
            temp_hai_str = function.akadora_hai_convert(j)
            if temp_hai_str in genbutsu_list:
                continue

            #字牌
            if hai_index > 30:
                if vertual_yama_index[hai_index] == 0:
                    continue
                elif vertual_yama_index[hai_index] == 1:
                    continue
                elif vertual_yama_index[hai_index] == 2:
                    danger_degree_list[j] += 0.05
                    continue
                elif vertual_yama_index[hai_index] == 3:
                    danger_degree_list[j] += 0.2
                    continue

            #筋牌ならばcontinue
            if suji_hantei(genbutsu_list, hai_index):
                continue

            #序盤に切れた数牌の外側ならばcontinue
            sutehai_len = len(janshi_list[i].sutehai)
            if sutehai_len > 6:
                sotohai_list = sotohai_find(janshi_list[i].sutehai,
                                            min(int(sutehai_len / 3), 4))
                if hai_index in sotohai_list:
                    continue

            #カベの外側continue
            if kabe_eval(vertual_yama_index, hai_index) != 0:
                continue

            #補正
            danger_degree_list[j] += tenpai_prob * 2.0

    danger_degree_list = np.array(danger_degree_list)
    danger_degree_list_return = np.array(danger_degree_list_return)

    return danger_degree_list + danger_degree_list_return
Example #8
0
def teyaku_check(janshi, taku, agarihai_str: [str]):

    #janshi,takuオブジェクトを引数に、そのjanshiのアガリ手牌の[符数,翻数,役リスト]を出力する。翻数(n倍役満:-n、役なし:0)
    #アガリ牌はjanshi.tehaiに含めて入力。
    fusuu = 20
    hansuu = 0
    yaku_list = []

    #変数の整理
    tehai_akadora = function.akadora_convert(janshi.tehai)[1]
    tehai_str = function.akadora_convert(janshi.tehai)[0]
    fuurohai = janshi.fuurohai
    ankan = janshi.ankan_list
    fuurosu = len(fuurohai) + len(ankan)
    tehai_plus_fuuro_len = len(tehai_str) + fuurosu * 3
    assert 13 <= tehai_plus_fuuro_len <= 14
    if tehai_plus_fuuro_len == 13:
        if function.hai_convert(agarihai_str) % 10 == 0:
            tehai_akadora += 1
            agarihai_str = function.akadora_hai_convert(agarihai_str)
        tehai_str.append(agarihai_str)
        tsumoagari = False
    else:
        assert agarihai_str in janshi.tehai
        if function.hai_convert(agarihai_str) % 10 == 0:
            agarihai_str = function.akadora_hai_convert(agarihai_str)
        tsumoagari = True
    tehai = tehai_fuuro_mix_convert(tehai_str, janshi.fuurohai,
                                    janshi.ankan_list)
    tehai_exc_fuuro = tehai_str
    riichi = janshi.riichi
    ippatsu = janshi.ippatsu_flag
    rinshan = janshi.rinshan_flag
    zikaze = janshi.kaze
    first_tsumo = janshi.first_tsumo_flag
    fuuro_akadora = janshi.fuuro_akadora_list
    chankan = taku.chankan_flag
    haitei = taku.haitei_flag
    is_fuuro = Is_fuuro(fuurohai)
    #場風
    cnv = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]
    bakaze = cnv[taku.kaze_honba[0]]
    #ドラ表示→ドラ
    str_to_num = {
        "5M": 0,
        "5P": 10,
        "5S": 20,
        "1m": 1,
        "2m": 2,
        "3m": 3,
        "4m": 4,
        "5m": 5,
        "6m": 6,
        "7m": 7,
        "8m": 8,
        "9m": 9,
        "1p": 11,
        "2p": 12,
        "3p": 13,
        "4p": 14,
        "5p": 15,
        "6p": 16,
        "7p": 17,
        "8p": 18,
        "9p": 19,
        "1s": 21,
        "2s": 22,
        "3s": 23,
        "4s": 24,
        "5s": 25,
        "6s": 26,
        "7s": 27,
        "8s": 28,
        "9s": 29,
        "1z": 31,
        "2z": 32,
        "3z": 33,
        "4z": 34,
        "5z": 35,
        "6z": 36,
        "7z": 37
    }
    dorah = [taku.dorahyouji, taku.uradorahyouji]
    #dora = [[ドラリスト],[裏ドラリスト]]
    dora = [[], []]
    for i in range(0, 2):
        for j in dorah[i]:
            j2 = str_to_num[j]
            if (j2 == 9) or (j2 == 19) or (j2 == 29):
                dora[i].append(j2 - 8)
            elif j2 == 34:
                dora[i].append(31)
            elif j2 == 37:
                dora[i].append(35)
            elif j2 % 10 == 0:
                dora[i].append(j2 + 6)
            else:
                dora[i].append(j2 + 1)
    agarihai = str_to_num[agarihai_str]
    fanpai = [tehai[31], tehai[32], tehai[33], tehai[34]]
    sangenpai = [tehai[35], tehai[36], tehai[37]]

    #アガリ形の判別(国士形:2、七対形:1、四面子一雀頭形:0、アガってない:-1)
    agari_kei = -1
    #国士形かどうか
    kokushi_flag = True
    kokushi_l = [1, 9, 11, 19, 21, 29, 31, 32, 33, 34, 35, 36, 37]
    for i in kokushi_l:
        if tehai[i] == 0:
            kokushi_flag = False
    if kokushi_flag == True:
        agari_kei = 2
    #七対形かどうか
    chiitoi_flag = True
    for i in range(1, 38):
        if tehai[i] == 1 or tehai[i] >= 3:
            chiitoi_flag = False
    if chiitoi_flag == True:
        agari_kei = 1
    #四面子一雀頭形の場合、雀頭と面子に分解して変換
    jm_list = jm_convert(tehai_exc_fuuro, fuurohai, ankan)
    if jm_list != []:
        agari_kei = 0
    if agari_kei == -1:
        return [0, 0, []]

    #個別の役について判定する
    #役満役
    yakuman = 0
    #天和
    if first_tsumo:
        yaku_list.append("天和")
        yakuman += 1
    #字一色
    if inc(tehai, '000000000 000000000 000000000 1111111'):
        yaku_list.append("字一色")
        yakuman += 1
    #緑一色
    if inc(tehai, '000000000 000000000 011101010 0000010'):
        yaku_list.append("緑一色")
        yakuman += 1
    #清老頭
    if inc(tehai, '100000001 100000001 100000001 0000000'):
        yaku_list.append("清老頭")
        yakuman += 1
    #大三元
    sangenpai = [tehai[35], tehai[36], tehai[37]]
    if sangenpai[0] >= 3 and sangenpai[1] >= 3 and sangenpai[2] >= 3:
        yaku_list.append("大三元")
        yakuman += 1
    #小四喜
    fanpai = [tehai[31], tehai[32], tehai[33], tehai[34]]
    if (fanpai[0] == 2 and fanpai[1] >= 3 and fanpai[2] >= 3 and fanpai[3] >= 3) or\
        (fanpai[0] >= 3 and fanpai[1] == 2 and fanpai[2] >= 3 and fanpai[3] >= 3) or\
            (fanpai[0] >= 3 and fanpai[1] >= 3 and fanpai[2] == 2 and fanpai[3] >= 3) or\
                (fanpai[0] >= 3 and fanpai[1] >= 3 and fanpai[2] >= 3 and fanpai[3] == 2):
        yaku_list.append("小四喜")
        yakuman += 1
    #大四喜
    fanpai = [tehai[31], tehai[32], tehai[33], tehai[34]]
    if fanpai[0] >= 3 and fanpai[1] >= 3 and fanpai[2] >= 3 and fanpai[3] >= 3:
        yaku_list.append("大四喜")
        yakuman += 1
    #九蓮宝橙:萬子
    tyuuren_flag = True
    if not inc(tehai, '111111111 000000000 000000000 0000000'):
        tyuuren_flag = False
    for i in range(1, 10):
        if i == (1 or 9):
            if tehai[i] < 3:
                tyuuren_flag = False
        if tehai[i] == 0:
            tyuuren_flag = False
    if tyuuren_flag == True and is_fuuro == False:
        yaku_list.append("九蓮宝橙")
        yakuman += 1
    #九蓮宝橙:筒子
    tyuuren_flag = True
    if not inc(tehai, '000000000 111111111 000000000 0000000'):
        tyuuren_flag = False
    for i in range(11, 20):
        if i == (11 or 19):
            if tehai[i] < 3:
                tyuuren_flag = False
        if tehai[i] == 0:
            tyuuren_flag = False
    if tyuuren_flag == True and is_fuuro == False:
        yaku_list.append("九蓮宝橙")
        yakuman += 1
    #九蓮宝橙:索子
    tyuuren_flag = True
    if not inc(tehai, '000000000 000000000 111111111 0000000'):
        tyuuren_flag = False
    for i in range(21, 30):
        if i == (21 or 29):
            if tehai[i] < 3:
                tyuuren_flag = False
        if tehai[i] == 0:
            tyuuren_flag = False
    if tyuuren_flag == True and is_fuuro == False:
        yaku_list.append("九蓮宝橙")
        yakuman += 1
    #四槓子
    if agari_kei == 0:
        for jm in jm_list:
            suukantsu_flag = True
            for m in jm[1]:
                if m[1] != 2:
                    suukantsu_flag = False
            if suukantsu_flag == True:
                yaku_list.append("四槓子")
                yakuman += 1
    #四暗刻
    if agari_kei == 0:
        for jm in jm_list:
            suuankou_flag = True
            for m in jm[1]:
                if m[0] != 0 or m[1] == 0:
                    suuankou_flag = False
            if not tsumoagari and jm[0] != agarihai:
                suuankou_flag = False
            if suuankou_flag == True:
                yaku_list.append("四暗刻")
                yakuman += 1
    #国士無双
    if kokushi_flag == True:
        yaku_list.append("国士無双")
        yakuman += 1
    #役満があったとき
    if yakuman != 0:
        return [-yakuman, 0, yaku_list]

    #役満以外の役
    #立直、ダブル立直
    if riichi == 1:
        yaku_list.append("立直")
        hansuu += 1
    if riichi == 2:
        yaku_list.append("ダブル立直")
        hansuu += 2
    #一発
    if ippatsu:
        yaku_list.append("一発")
        hansuu += 1
    #メンゼン自摸
    if tsumoagari and not is_fuuro:
        yaku_list.append("門前清自摸和")
        hansuu += 1
    #嶺上開花
    if rinshan:
        yaku_list.append("嶺上開花")
        hansuu += 1
    #海底、河底
    if haitei:
        yaku_list.append("ハイテイ")
        hansuu += 1
    #槍槓
    if chankan:
        yaku_list.append("槍槓")
        hansuu += 1
    #断么九
    if inc(tehai, '011111110 011111110 011111110 0000000'):
        yaku_list.append("断么九")
        hansuu += 1
    #混老頭
    if inc(tehai, '100000001 100000001 100000001 1111111'):
        yaku_list.append("混老頭")
        hansuu += 2
    #清一色
    tinitsu_flag = False
    if inc(tehai,'111111111 000000000 000000000 0000000') or inc(tehai,'000000000 1111111111 000000000 0000000')\
    or inc(tehai,'000000000 000000000 111111111 0000000'):
        yaku_list.append("清一色")
        tinitsu_flag = True
        if is_fuuro:
            hansuu += 5
        else:
            hansuu += 6
    #混一色
    if tinitsu_flag == False and ( inc(tehai,'111111111 000000000 000000000 1111111')\
    or inc(tehai,'000000000 111111111 000000000 1111111') or inc(tehai,'000000000 000000000 111111111 1111111')):
        yaku_list.append("混一色")
        if is_fuuro:
            hansuu += 2
        else:
            hansuu += 3
    #白、發、中
    sangenpai = [tehai[35], tehai[36], tehai[37]]
    if sangenpai[0] >= 3:
        yaku_list.append("白")
        hansuu += 1
    if sangenpai[1] >= 3:
        yaku_list.append("發")
        hansuu += 1
    if sangenpai[2] >= 3:
        yaku_list.append("中")
        hansuu += 1
    #小三元
    sangenpai = [tehai[35], tehai[36], tehai[37]]
    if (sangenpai[0] >= 3 and sangenpai[1] >= 3 and sangenpai[2] == 2) or\
        (sangenpai[0] >= 3 and sangenpai[1] == 2 and sangenpai[2] >= 3) or\
            (sangenpai[0] == 2 and sangenpai[1] >= 3 and sangenpai[2] >= 3):
        yaku_list.append("小三元")
        hansuu += 2
    #場風、自風
    if tehai[31 + bakaze] >= 3:
        yaku_list.append("場風")
        hansuu += 1
    if tehai[31 + zikaze] >= 3:
        yaku_list.append("自風")
        hansuu += 1
    #七対子
    if agari_kei == 1:
        yaku_list.append("七対子")
        hansuu += 2
        fusuu = 25
    #三槓子
    if agari_kei == 0:
        kantsu_num = 0
        for jm in jm_list:
            for m in jm[1]:
                if m[1] == 2:
                    kantsu_num += 1
            if kantsu_num >= 3:
                yaku_list.append("三槓子")
                hansuu += 2

    #面子の分解パターンによってついたりつかなかったりする役(四暗刻をのぞく)
    #すべての分解パターンについて求め、最も翻数、符数が高いものをえらぶ。
    if agari_kei == 0:
        han_fu_candidate = []
        for jm in jm_list:
            hansuu_tmp = hansuu
            fusuu_tmp = fusuu
            yaku_list_tmp = copy(yaku_list)

            #符計算
            shuntsu_lis = [i for i in jm[1] if i[1] == 0]  #順子を入れた配列
            #符(雀頭)
            yakuhai_jantou_flag = False
            if jm[0] == 35 or jm[0] == 36 or jm[0] == 37 or jm[
                    0] == 31 + zikaze or jm[0] == 31 + bakaze:
                fusuu_tmp += 2
                yakuhai_jantou_flag = True
            #符(待ち)
            #待ち方が複数解釈できる場合平和がつく(符数20)なら両面。それ以外は符がつく待ちを選ぶ。(シャボvs両面は両面(for三暗刻))
            #順子数>3の時、両面待ちがあるならピンフ。ないなら符数+2
            pinfu_flag = False
            ryanmen = [[], [1], [2, 4], [3, 5], [4, 6], [5, 7], [6, 8],
                       [9], [], [], [], [11], [12, 14], [13, 15], [14, 16],
                       [15, 17], [16, 18], [19], [], [], [], [21], [22, 24],
                       [23, 25], [24, 26], [25, 27], [26, 28], [29], [], []]
            if len(shuntsu_lis) > 3:
                for i in shuntsu_lis:
                    r = ryanmen[i[2]]
                    if len(r) > 0:
                        for j in r:
                            if agarihai < 30 and agarihai == j and yakuhai_jantou_flag == False:
                                pinfu_flag = True
                if pinfu_flag == False:
                    fusuu_tmp += 2
            #順子数<=3の時、符が付く待ち→両面の順に探す。どれもなければシャボ。シャボの場合、ロンアガリならjmのその暗刻を明刻に変える。
            else:
                tanki_flag = False
                penchan_flag = False
                kanchan_flag = False
                ryanmen_flag = False
                penchan = [
                    0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 17, 0,
                    0, 0, 23, 0, 0, 0, 0, 0, 27, 0, 0
                ]
                kanchan = [
                    0, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 12, 13, 14, 15, 16, 17,
                    18, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 0, 0
                ]
                if agarihai == jm[0]:
                    tanki_flag = True
                elif len(shuntsu_lis) > 0 and agarihai < 30:
                    for i in shuntsu_lis:
                        if agarihai == penchan[i[2]]:
                            penchan_flag = True
                        elif agarihai == kanchan[i[2]]:
                            kanchan_flag = True
                        else:
                            r = ryanmen[i[2]]
                            if len(r) > 0:
                                for j in r:
                                    if agarihai == j:
                                        ryanmen_flag = True
                if tanki_flag == True or penchan_flag == True or kanchan_flag == True:
                    fusuu_tmp += 2
                elif ryanmen_flag == False and not tsumoagari:
                    for l in jm[1]:
                        if l[1] == 1 and l[2] == agarihai:
                            l[0] = 1
            #刻子、暗刻を入れた配列
            koutsu_lis = [i for i in jm[1] if i[1] == 1 or i[1] == 2]  #槓子含む
            anko_lis = [i for i in koutsu_lis if i[0] == 0]  #槓子含む
            #符(刻子、槓子)
            if len(koutsu_lis) > 0:
                for l in koutsu_lis:
                    if (1 < l[2] < 9) or (11 < l[2] < 19) or (21 < l[2] < 29):
                        yaotyu = 0
                    else:
                        yaotyu = 1
                    if l[0] == 1:
                        ank = 0
                    else:
                        ank = 1
                    if l[1] == 1:
                        kant = 0
                    else:
                        kant = 1
                    fusuu_tmp += 2 * (2**yaotyu) * (2**ank) * (4**kant)
            #符(上がり方)
            if tsumoagari and pinfu_flag == False:
                fusuu_tmp += 2
            elif not tsumoagari and not is_fuuro:
                fusuu_tmp += 10

            #順子が3個以上ならすべての三順子のインデックスを抜き出す。同順、イッツー用
            if len(shuntsu_lis) >= 3:
                san_shuntsu_id = []
                if len(shuntsu_lis) == 3:
                    san_shuntsu_id.append([i[2] for i in shuntsu_lis])
                else:
                    yon_shuntsu_id = [i[2] for i in shuntsu_lis]
                    for i in range(0, 4):
                        san_shuntsu_id.append(yon_shuntsu_id[:i] +
                                              yon_shuntsu_id[(i + 1):])
                for i in san_shuntsu_id:
                    i.sort()
            #刻子が3個以上ならすべての三刻子のインデックスを抜き出す。同刻用。
            if len(koutsu_lis) >= 3:
                san_koutsu_id = []
                if len(koutsu_lis) == 3:
                    san_koutsu_id.append([i[2] for i in koutsu_lis])
                else:
                    yon_koutsu_id = [i[2] for i in koutsu_lis]
                    for i in range(0, 4):
                        san_koutsu_id.append(yon_koutsu_id[:i] +
                                             yon_koutsu_id[(i + 1):])
                for i in san_koutsu_id:
                    i.sort()
            #一盃口、二盃口
            if not is_fuuro:
                l = len(shuntsu_lis)
                if l >= 2:
                    peko_num = 0
                    for i in range(0, l - 1):
                        for j in range(i + 1, l):
                            if shuntsu_lis[i][2] == shuntsu_lis[j][2]:
                                peko_num += 1
                    if peko_num == 1:
                        yaku_list_tmp.append("一盃口")
                        hansuu_tmp += 1
                    elif peko_num == 2:
                        yaku_list_tmp.append("二盃口")
                        hansuu_tmp += 3
            #三暗刻
            if len(anko_lis) == 3:
                yaku_list_tmp.append("三暗刻")
                hansuu_tmp += 2
            #三色同刻
            if len(koutsu_lis) >= 3:
                doukou_flag = False
                for s in san_koutsu_id:
                    if s[1] == s[0] + 10 and s[2] == s[0] + 20 and s[2] < 30:
                        doukou_flag = True
                if doukou_flag == True:
                    yaku_list_tmp.append("三色同刻")
                    hansuu_tmp += 2
            #三色同順
            if len(shuntsu_lis) >= 3:
                doujun_flag = False
                for s in san_shuntsu_id:
                    if s[1] == s[0] + 10 and s[2] == s[0] + 20:
                        doujun_flag = True
                if doujun_flag == True:
                    yaku_list_tmp.append("三色同順")
                    if is_fuuro:
                        hansuu_tmp += 1
                    else:
                        hansuu_tmp += 2
            #対々和
            if len(koutsu_lis) >= 4:
                yaku_list_tmp.append("対々和")
                hansuu_tmp += 2
            #一気通貫
            if len(shuntsu_lis) >= 3:
                ittsu_flag = False
                for s in san_shuntsu_id:
                    if s == ([1, 4, 7] or [11, 14, 17] or [21, 24, 27]):
                        ittsu_flag = True
                if ittsu_flag == True:
                    yaku_list_tmp.append("一気通貫")
                    if is_fuuro:
                        hansuu_tmp += 1
                    else:
                        hansuu_tmp += 2
            #純全帯么九、混全帯么九
            junchan_flag = True
            chanta_flag = True
            if len(shuntsu_lis) >= 1:
                for l in shuntsu_lis:
                    if (1 < l[2] < 7) or (11 < l[2] < 17) or (21 < l[2] < 27):
                        junchan_flag = False
                        chanta_flag = False
            if len(koutsu_lis) >= 1:
                for l in koutsu_lis:
                    if (1 < l[2] < 9) or (11 < l[2] < 19) or (21 < l[2] < 29):
                        junchan_flag = False
                        chanta_flag = False
                    elif 30 < l[2]:
                        junchan_flag = False
            if (1 < jm[0] < 7) or (11 < jm[0] < 17) or (21 < jm[0] < 27):
                junchan_flag = False
                chanta_flag = False
            elif 30 < jm[0]:
                junchan_flag = False
            if junchan_flag == True:
                yaku_list_tmp.append("純全帯么九")
                if is_fuuro:
                    hansuu_tmp += 2
                else:
                    hansuu_tmp += 3
            elif chanta_flag == True:
                yaku_list_tmp.append("混全帯么九")
                if is_fuuro:
                    hansuu_tmp += 1
                else:
                    hansuu_tmp += 2
            #平和
            if pinfu_flag == True and not is_fuuro:
                yaku_list_tmp.append("平和")
                hansuu_tmp += 1
            han_fu_candidate.append([hansuu_tmp, fusuu_tmp, yaku_list_tmp])

        for i in han_fu_candidate:
            if i[0] > hansuu:
                hansuu = i[0]
                fusuu = i[1]
                yaku_list = i[2]
            elif i[0] == hansuu:
                if i[1] > fusuu:
                    fusuu = i[1]
                    yaku_list = i[2]

    if hansuu > 0:
        od = 0
        for i in dora[0]:
            od += tehai[i]
        if od > 0:
            yaku_list.append("ドラ" + str(od))
            hansuu += od
        ad = tehai_akadora
        if len(fuuro_akadora) > 0:
            for i in fuuro_akadora:
                if i:
                    ad += 1
        if len(ankan) > 0:
            for i in ankan:
                if i == 5 or i == 15 or i == 25:
                    ad += 1
        if ad > 0:
            yaku_list.append("赤ドラ" + str(ad))
            hansuu += ad
        if riichi > 0:
            ud = 0
            for i in dora[1]:
                ud += tehai[i]
            if ud > 0:
                yaku_list.append("裏ドラ" + str(ud))
                hansuu += ud
    if fusuu != 25:
        fusuu2 = fusuu / 10.0
        fusuu = math.ceil(fusuu2) * 10

    return [hansuu, fusuu, yaku_list]