def new_yuukouhai_explore(shanten_suu, janshi, taku):
    hash_table = taku.hash_table
    #tehai = np.array(function.tehai_convert(janshi.tehai))
    #ツモって来る牌に赤ドラは考慮しない
    yama = np.array(
        function.tehai_convert(
            function.akadora_convert(janshi.vertual_yama)[0]))
    init_shanten_suu = shanten_suu
    #index_list = [0]*len(tehai)
    sum_val = 0
    #mean_list = [0]*len(tehai)
    #hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    #print(hai_list)

    #print(hai_list)
    if init_shanten_suu >= 3:
        itr = 15
    else:
        itr = 25

    for j in range(itr):
        count = 1.
        temp_janshi = copy.deepcopy(janshi)
        if len(temp_janshi.fuurohai) == 0:
            temp_janshi.riichi = 1
        temp_yama = yama.copy()
        sum_val += yuukouhai_explore(temp_yama, init_shanten_suu, count,
                                     hash_table, temp_janshi, taku)
    sum_val /= float(itr)
    return sum_val
def new_yuukouhai_explore(shanten_suu, janshi, taku):
    hash_table = taku.hash_table
    tehai = np.array(function.tehai_convert(janshi.tehai))

    #ツモって来る牌に赤ドラは考慮しない
    yama = np.array(
        function.tehai_convert(
            function.akadora_convert(janshi.vertual_yama)[0]))
    init_shanten_suu = shanten_suu
    #index_list = [0]*len(tehai)
    sum_list = [0] * len(tehai)
    #mean_list = [0]*len(tehai)
    hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    #print(hai_list)
    #副露した時でアガリ役なしの場合
    if len(hai_list) == 0:
        return random.choice(range(len(janshi.tehai))), 0

    #バグ防止用
    for i in hai_list:
        sum_list[i] += 0.001

    #print(hai_list)
    itr = 25

    for i in hai_list:
        for j in range(itr):
            count = 1.
            temp_janshi = copy.deepcopy(janshi)
            temp_tehai = tehai.copy()
            temp_yama = yama.copy()
            temp_tehai[i] -= 1
            temp_janshi.tehai = function.tehai_convert_reverse(temp_tehai)
            a = yuukouhai_explore(temp_yama, init_shanten_suu, count,
                                  hash_table, temp_janshi, taku)
            #index_list[i] += 1
            sum_list[i] += a
        sum_list[i] /= float(itr)

    #for i in range(len(tehai)):
    #    mean_list[i] = sum_list[i]/float(itr)

    maximum_index_num = -1
    #print(janshi.tehai)
    #print(np.round(sum_list,2))

    maximum_expect = np.max(sum_list)
    return_hai_str = function.hai_convert_reverse(np.argmax(sum_list))
    #print(return_hai_str)

    for i in range(len(janshi.tehai)):
        if janshi.tehai[i] == return_hai_str:
            maximum_index_num = i
            break
    #print(maximum_index_num)
    assert maximum_index_num >= 0
    return maximum_index_num, maximum_expect
def new_yuukouhai_explore(shanten_suu, janshi, taku, kuikae_list):
    hash_table = taku.hash_table
    tehai = np.array(function.tehai_convert(janshi.tehai))
    yama = np.array(function.tehai_convert(function.akadora_convert(janshi.vertual_yama)[0]))
    init_shanten_suu = shanten_suu
    sum_list = [0]*len(tehai)
    hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    
    #hai_listからkuikae_listを削除
    temp_hai_list = hai_list.copy()
    for i in range(len(hai_list)):
        if temp_hai_list[i] in kuikae_list:
            hai_list.remove(temp_hai_list)
    
    #副露した時でアガリ役なしの場合
    if len(hai_list) == 0:
        return random.choice(range(len(janshi.tehai))), 0
    
    #バグ防止用
    for i in hai_list:
        sum_list[i] += 0.001
    
    itr = 25
    
    for j in range(itr):
        count = 1.      
        for i in hai_list:
            temp_janshi = copy.deepcopy(janshi)
            temp_tehai = tehai.copy()
            temp_yama = yama.copy()       
            temp_tehai[i] -= 1
            temp_janshi.tehai = function.tehai_convert_reverse(temp_tehai)
            a = yuukouhai_explore(temp_yama, init_shanten_suu, count, hash_table, temp_janshi, taku)
            sum_list[i] += a
    
    maximum_index_num = -1
    
    maximum_expect = np.max(sum_list)
    return_hai_str = function.hai_convert_reverse(np.argmax(sum_list))
    
    for i in range(len(janshi.tehai)):
        if janshi.tehai[i] == return_hai_str:
            maximum_index_num = i
            break
    assert maximum_index_num >= 0
    return maximum_index_num, maximum_expect
示例#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)
def eval_tehai_point(janshi, taku):

    #デバッグモード
    debug_mode = 0

    #パラメータ関連

    #各シャンテン数に対する平均有効牌枚数
    mean_list = [
        4.575752953784895, 12.18668553881974, 23.338351152742664,
        40.50627978155267, 60.56931288649266, 77.81782501846193,
        100.03097486813587
    ]

    shanten_bonus = 5
    yuukouhai_bonus = 2.0
    yuukouhai_pow_const = 1.0
    dora_bonus0 = 1.1  #ドラインデックスの牌
    dora_bonus1 = 0.6  #ドラインデックス前後の牌
    dora_bonus2 = 0.3  #ドラインデックスから2枚離れた牌
    yakuhai_bonus = [0, 0.2, 0.7, 1.2]  #0枚~3枚以上
    ryanmen_bonus = 0.3
    penchan_penalty = -0.5
    koritsu_yaochu_penalty = -0.25  #1,9
    koritsu_suuhai_penalty2 = -0.05  #2,8
    koritsu_suuhai_penalty3 = -0.01  #3~7
    koritsu_jihai_penalty = -0.33
    koritsu_nokori_yakuhai_penalty = [-0.5, -0.35, -0.2, 0.0]
    toitsu_nokori_yakuhai_penalty = [-1.2, -0.7, 0.0, 0.0]
    koritsu_nokori_jihai_penalty = [-0.3, -0.2, -0.1, 0.0]
    toitsu_nokori_jihai_penalty = [-0.4, -0.3, 0.0, 0.0]
    tanyao_bonus = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.3, 0.6, 1.0]
    ittsuu_bonus = [0, 0, 0, 0, 0, 0, 0.2, 0.7, 1.1, 1.4]
    sansyoku_bonus = [0, 0, 0, 0, 0, 0, 0.2, 0.8, 1.2, 1.6]
    honitsu_bonus = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1.0, 2.0, 3.0]
    yipeko_param1 = 1.0  #222
    yipeko_param2 = 0.8  #122, 221
    yipeko_param3 = 0.6  #212
    yipeko_param4 = 0.5  #212(1,9含む)
    yipeko_param5 = 0.4  #221, 122(1,9含む)
    furiten_penalty = [-0.2, -0.5, -0.2]
    furiten_penalty_for_yuukouhai = -0.4
    mentsu_bonus = 1.0

    #メイン
    eval_point_list = [0] * len(janshi.tehai)
    old_shanten_suu = shanten_check_new.shanten_check(janshi, taku.hash_table)
    for i in range(len(janshi.tehai)):

        if debug_mode:
            print("捨てる牌: " + janshi.tehai[i])

        #コピーして手牌を1つ削除
        temp_janshi = copy.deepcopy(janshi)
        temp_janshi.sutehai.append(temp_janshi.tehai[i])
        del temp_janshi.tehai[i]

        #赤ドラだけ抜き出してあとは赤ナシで考える
        temp = function.akadora_convert(temp_janshi.tehai)
        akadora_maisuu = temp[1]
        temp_janshi.tehai = temp[0]
        tehai = function.tehai_convert(temp_janshi.tehai)

        #vertual_yama
        vertual_yama_index = function.tehai_convert(temp_janshi.vertual_yama)
        #print(vertual_yama_index)

        #メンツカウント
        mentsu_suu = mentsu_count.mentsu_count(temp_janshi)
        mentsu_point = mentsu_suu * mentsu_bonus
        eval_point_list[i] += mentsu_point
        if debug_mode:
            print("メンツボーナス: " + str(mentsu_point))

        #シャンテン数関連

        new_shanten_suu = shanten_check_new.shanten_check(
            temp_janshi, taku.hash_table)
        if old_shanten_suu == new_shanten_suu:
            eval_point_list[i] += shanten_bonus
            if debug_mode:
                print("シャンテンアップボーナス: " + str(shanten_bonus))
        else:
            if debug_mode:
                print("シャンテンアップボーナス: " + str(0))
        #print(eval_point_list[i])

        #有効牌関連
        yuukouhai_maisuu = function.calc_yuukouhai_maisuu(
            temp_janshi, new_shanten_suu, taku.hash_table)
        yuukouhai_point = ((yuukouhai_maisuu /
                            (len(temp_janshi.vertual_yama) / 123.0 *
                             mean_list[new_shanten_suu]))**
                           yuukouhai_pow_const) * yuukouhai_bonus
        eval_point_list[i] += yuukouhai_point
        if debug_mode:
            print("有効牌ボーナス: " + str(yuukouhai_point))
        #print(eval_point_list[i])

        #ドラ関連とりあえず1枚の時だけ
        dora_index = []
        dora_hyouji_index = function.tehai_convert2(
            function.akadora_convert(taku.dorahyouji)[0]).copy()
        for j in range(len(taku.dorahyouji)):
            ##まずドラのインデックスを求める
            if dora_hyouji_index[j] < 30:
                if dora_hyouji_index[j] % 10 == 9:
                    dora_index.append(dora_hyouji_index[j] - 8)
                else:
                    dora_index.append(dora_hyouji_index[j] + 1)
            else:
                if dora_hyouji_index[j] == 34:
                    dora_index.append(31)
                elif dora_hyouji_index[j] == 37:
                    dora_index.append(35)
                else:
                    dora_index.append(dora_hyouji_index[j] + 1)

        dora_point = 0

        #赤ドラ
        dora_point += akadora_maisuu * dora_bonus0

        for j in range(len(dora_index)):
            if dora_index[j] < 30:
                if dora_index[j] % 10 == 1:
                    dora_point += tehai[dora_index[j]] * dora_bonus0
                    dora_point += bool(tehai[dora_index[j] + 1]) * dora_bonus1
                    dora_point += bool(tehai[dora_index[j] + 2]) * dora_bonus2
                elif dora_index[j] % 10 == 2:
                    dora_point += bool(tehai[dora_index[j] - 1]) * dora_bonus2
                    dora_point += tehai[dora_index[j]] * dora_bonus0
                    dora_point += bool(tehai[dora_index[j] + 1]) * dora_bonus1
                    dora_point += bool(tehai[dora_index[j] + 2]) * dora_bonus2
                elif dora_index[j] % 10 == 8:
                    dora_point += bool(tehai[dora_index[j] - 2]) * dora_bonus2
                    dora_point += bool(tehai[dora_index[j] - 1]) * dora_bonus1
                    dora_point += tehai[dora_index[j]] * dora_bonus0
                    dora_point += bool(tehai[dora_index[j] + 1]) * dora_bonus2
                elif dora_index[j] % 10 == 1:
                    dora_point += tehai[dora_index[j]] * dora_bonus0
                    dora_point += bool(tehai[dora_index[j] - 1]) * dora_bonus1
                    dora_point += bool(tehai[dora_index[j] - 2]) * dora_bonus2
                else:
                    dora_point += bool(tehai[dora_index[j] - 2]) * dora_bonus2
                    dora_point += bool(tehai[dora_index[j] - 1]) * dora_bonus1
                    dora_point += tehai[dora_index[j]] * dora_bonus0
                    dora_point += bool(tehai[dora_index[j] + 1]) * dora_bonus1
                    dora_point += bool(tehai[dora_index[j] + 2]) * dora_bonus2
            else:
                dora_point += tehai[dora_index[j]] * dora_bonus0

        eval_point_list[i] += dora_point
        if debug_mode:
            print("ドラボーナス: " + str(dora_point))
        #print(eval_point_list[i])

        #役牌
        if taku.kaze_honba[0] < 4:
            bakaze_index = 31
        else:
            bakaze_index = 32
        jikaze_index = temp_janshi.kaze + 31

        yakuhai_point = 0
        yakuhai_point += yakuhai_bonus[tehai[bakaze_index]]
        yakuhai_point += yakuhai_bonus[tehai[jikaze_index]]
        yakuhai_point += yakuhai_bonus[tehai[35]]
        yakuhai_point += yakuhai_bonus[tehai[36]]
        yakuhai_point += yakuhai_bonus[tehai[37]]

        #ペナ
        if tehai[bakaze_index] == 1:
            yakuhai_point += koritsu_nokori_yakuhai_penalty[
                vertual_yama_index[bakaze_index]]
        elif tehai[bakaze_index] == 2:
            yakuhai_point += toitsu_nokori_yakuhai_penalty[
                vertual_yama_index[bakaze_index]]

        if tehai[jikaze_index] == 1:
            yakuhai_point += koritsu_nokori_yakuhai_penalty[
                vertual_yama_index[jikaze_index]]
        elif tehai[jikaze_index] == 2:
            yakuhai_point += toitsu_nokori_yakuhai_penalty[
                vertual_yama_index[jikaze_index]]

        for j in range(3):
            if tehai[35 + j] == 1:
                yakuhai_point += koritsu_nokori_yakuhai_penalty[
                    vertual_yama_index[35 + j]]
            elif tehai[35 + j] == 2:
                yakuhai_point += toitsu_nokori_yakuhai_penalty[
                    vertual_yama_index[35 + j]]

        #役牌以外の字牌に対するペナ
        for j in range(4):
            if 31 + j != bakaze_index and 31 + j != jikaze_index:
                if tehai[31 + j] == 1:
                    yakuhai_point += koritsu_nokori_jihai_penalty[
                        vertual_yama_index[31 + j]]
                elif tehai[31 + j] == 2:
                    yakuhai_point += toitsu_nokori_jihai_penalty[
                        vertual_yama_index[31 + j]]

        eval_point_list[i] += yakuhai_point
        if debug_mode:
            print("役牌ボーナス: " + str(yakuhai_point))
        #print(eval_point_list[i])

        #リャンメンボーナス(テスト)
        ryanmen_point = 0
        for j in range(30):
            if 2 <= j % 10 <= 7:
                if tehai[j - 1] == 0 and tehai[j] >= 1 and tehai[
                        j + 1] >= 1 and tehai[j + 2] == 0:
                    ryanmen_point += ryanmen_bonus
        eval_point_list[i] += ryanmen_point
        if debug_mode:
            print("リャンメンボーナス: " + str(ryanmen_point))
        #print(eval_point_list[i])

        #ペンチャンペナルティ
        penchan_point = 0
        for j in range(30):
            if j % 10 == 1 or j % 10 == 8:
                if tehai[j - 1] == 0 and tehai[j] == 1 and tehai[
                        j + 1] == 1 and tehai[j + 2] == 0:
                    penchan_point += penchan_penalty
                elif tehai[j - 1] == 0 and tehai[j] >= 1 and tehai[
                        j + 1] >= 1 and tehai[j + 2] == 0:
                    penchan_point += penchan_penalty * 0.1
        if debug_mode:
            print("ペンチャンペナルティ: " + str(penchan_point))
        eval_point_list[i] += penchan_point

        #孤立牌ペナルティandフリテンペナルティ
        koritsu_suuhai_point = 0
        koritsu_jihai_point = 0
        koritsu_list = function.tehai_koritsu_hantei(temp_janshi.tehai)
        for j in koritsu_list:
            koritsu_index = function.hai_convert(temp_janshi.tehai[j])
            if koritsu_index < 30:
                if (koritsu_index % 10 == 2) or (koritsu_index % 10 == 8):
                    koritsu_suuhai_point += koritsu_suuhai_penalty2
                elif 3 <= koritsu_index % 10 <= 7:
                    koritsu_suuhai_point += koritsu_suuhai_penalty3
                else:
                    koritsu_suuhai_point += koritsu_yaochu_penalty
            else:
                koritsu_jihai_point += koritsu_jihai_penalty

        eval_point_list[i] += koritsu_suuhai_point
        if debug_mode:
            print("孤立数牌ペナルティ: " + str(koritsu_suuhai_point))
        eval_point_list[i] += koritsu_jihai_point
        if debug_mode:
            print("孤立字牌ペナルティ: " + str(koritsu_jihai_point))
        #print(eval_point_list[i])

        #フリテンペナルティ 孤立牌がフリテン絡みand有効牌がフリテン絡み
        furiten_point = 0
        kawa_no_akadora = function.tehai_convert(
            function.akadora_convert(temp_janshi.sutehai)[0])
        for j in range(len(kawa_no_akadora)):
            kawa_no_akadora[j] = bool(kawa_no_akadora[j])

        #孤立牌に対して
        for j in koritsu_list:
            koritsu_index = function.hai_convert(temp_janshi.tehai[j])
            if koritsu_index < 30:
                if 2 <= koritsu_index % 10 <= 8:
                    if kawa_no_akadora[koritsu_index - 2]:
                        furiten_point += furiten_penalty[2]
                    if kawa_no_akadora[koritsu_index - 1]:
                        furiten_point += furiten_penalty[1]
                    if kawa_no_akadora[koritsu_index]:
                        furiten_point += furiten_penalty[0]
                    if kawa_no_akadora[koritsu_index + 1]:
                        furiten_point += furiten_penalty[1]
                    if kawa_no_akadora[koritsu_index + 2]:
                        furiten_point += furiten_penalty[2]
                elif koritsu_index % 10 == 1:
                    if kawa_no_akadora[koritsu_index]:
                        furiten_point += furiten_penalty[0]
                    if kawa_no_akadora[koritsu_index + 1]:
                        furiten_point += furiten_penalty[1]
                    if kawa_no_akadora[koritsu_index + 2]:
                        furiten_point += furiten_penalty[2]
                elif koritsu_index % 10 == 9:
                    if kawa_no_akadora[koritsu_index - 2]:
                        furiten_point += furiten_penalty[2]
                    if kawa_no_akadora[koritsu_index - 1]:
                        furiten_point += furiten_penalty[1]
                    if kawa_no_akadora[koritsu_index]:
                        furiten_point += furiten_penalty[0]
            else:
                if kawa_no_akadora[koritsu_index]:
                    furiten_point += furiten_penalty[0]

        #有効牌に対して
        yuukouhai_index_list = function.find_yuukouhai(temp_janshi,
                                                       new_shanten_suu,
                                                       taku.hash_table)
        for index in yuukouhai_index_list:
            if kawa_no_akadora[index]:
                furiten_point += furiten_penalty_for_yuukouhai
        eval_point_list[i] += furiten_point
        if debug_mode:
            print("フリテンペナルティ: " + str(furiten_point))

        #タンヤオボーナス
        tanyao_point = 0
        tanyao_sum = function.tanyao_sum_up(temp_janshi)
        tanyao_point = tanyao_bonus[tanyao_sum]
        eval_point_list[i] += tanyao_point
        if debug_mode:
            print("タンヤオボーナス: " + str(tanyao_point))
        #print(eval_point_list[i])

        #一通ボーナス
        ittsuu_point = 0
        for j in range(3):
            ittsuu_point += ittsuu_bonus[function.ittsuu_sum_up(
                temp_janshi, j)]
        eval_point_list[i] += ittsuu_point
        if debug_mode:
            print("一通ボーナス: " + str(ittsuu_point))
        #print(eval_point_list[i])

        #三色ボーナス
        sansyoku_point = 0
        for j in range(1, 8):
            sansyoku_point += sansyoku_bonus[function.sansyoku_sum_up(
                temp_janshi, j)]
        eval_point_list[i] += sansyoku_point
        if debug_mode:
            print("三色ボーナス: " + str(sansyoku_point))

        #ホンイツボーナス
        honitsu_point = 0
        for j in range(3):
            honitsu_point += honitsu_bonus[function.honitsu_sum_up(
                temp_janshi, j)]
        eval_point_list[i] += honitsu_point
        if debug_mode:
            print("ホンイツボーナス: " + str(honitsu_point))

        #一盃口ボーナス
        yipeko_point = 0
        for j in range(3):
            yipeko_point += function.yipeko_eval(janshi, j, yipeko_param1,
                                                 yipeko_param2, yipeko_param3,
                                                 yipeko_param4, yipeko_param5)
        eval_point_list[i] += yipeko_point
        if debug_mode:
            print("一盃口ボーナス: " + str(yipeko_point))

        if debug_mode:
            print("  トータルポイント: " + str(eval_point_list[i]))
            print()
    eval_point_array = np.array(eval_point_list)
    normalized_eval_point_array = eval_point_array / np.sum(eval_point_array)
    return normalized_eval_point_array
def new_yuukouhai_explore(shanten_suu, janshi, taku):
    #print("aaaaaaaaaaaaaaaaaaaaa")
    global sum_list, pure_point_sum
    hash_table = taku.hash_table
    tehai = np.array(function.tehai_convert(janshi.tehai))

    #ツモって来る牌に赤ドラは考慮しない
    yama = np.array(
        function.tehai_convert(
            function.akadora_convert(janshi.vertual_yama)[0]))
    init_shanten_suu = shanten_suu
    #index_list = [0]*len(tehai)
    sum_list = [0] * len(tehai)
    pure_point_sum = [0] * len(tehai)
    #mean_list = [0]*len(tehai)
    if shanten_suu >= 2:
        hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    #テンパイならシャンテン戻しも考える
    else:
        hai_list = function.tehai_convert3(janshi.tehai)

    #print(hai_list)
    #副露した時でアガリ役なしの場合
    if len(hai_list) == 0:
        #print("no_hai_list_error")
        return [0.001] * len(janshi.tehai), [0.001] * len(
            janshi.tehai), [0.001] * len(janshi.tehai)

    #バグ防止用
    for i in hai_list:
        sum_list[i] += 0.001

    #print(hai_list)
    if init_shanten_suu >= 2:
        itr = 25
    elif init_shanten_suu == 1:
        itr = 20
    else:
        itr = 15

    temp_list = [(hai_id, janshi, yama, taku, shanten_suu, pure_point_sum, itr)
                 for hai_id in hai_list]
    p = Pool(multi.cpu_count())
    p.map(test_process, range(1000))
    p.close()
    '''
    for i in hai_list:
        for j in range(itr):
            count = 1.0
            temp_janshi = copy.deepcopy(janshi)
            #temp_tehai = tehai.copy()
            temp_yama = yama.copy() 
            #temp_tehai[i] -= 1
            temp_janshi.tehai.remove(function.hai_convert_reverse(i)) # = function.tehai_convert_reverse(temp_tehai)
            temp_janshi.sutehai.append(function.hai_convert_reverse(i))
            if j == 0:
                init_shanten_suu = shanten_check_new.shanten_check(temp_janshi, taku.hash_table)
            a, b = yuukouhai_explore(temp_yama, init_shanten_suu, count, hash_table, temp_janshi, taku)
            #index_list[i] += 1
            sum_list[i] += a
            pure_point_sum[i] += b
        #shanten_suu + 1で平均打点を割る
        pure_point_sum[i] /= max(init_shanten_suu + 1, 1)*itr
    '''

    #print(np.max(sum_list))

    normalized_index_list = np.array(sum_list) / np.sum(np.array(sum_list))
    normalized_list = np.zeros(len(janshi.tehai))
    sum_list_for_tehai_str = np.zeros(len(janshi.tehai))
    pure_point_sum_for_tehai_str = np.zeros(len(janshi.tehai))

    for i in range(len(janshi.tehai)):
        normalized_list[i] = normalized_index_list[function.hai_convert(
            janshi.tehai[i])]
        sum_list_for_tehai_str[i] = sum_list[function.hai_convert(
            janshi.tehai[i])]
        pure_point_sum_for_tehai_str[i] = pure_point_sum[function.hai_convert(
            janshi.tehai[i])]

    sum_list_for_tehai_str = np.array(sum_list_for_tehai_str)
    mean_list_for_tehai_str = sum_list_for_tehai_str / float(itr)
    pure_point_sum_for_tehai_str = np.array(pure_point_sum_for_tehai_str)

    return normalized_list, mean_list_for_tehai_str, pure_point_sum_for_tehai_str
示例#7
0
def shanten_check(janshi, hash_table):
    tehai = function.tehai_convert(function.akadora_convert(janshi.tehai)[0])
    fuurosu = len(janshi.fuurohai) + len(janshi.ankan_list)

    #国士無双形
    Sh_kokushi = 13  # ここから1、9、字牌の数を引いていく
    kokushi_l = [1, 9, 11, 19, 21, 29, 31, 32, 33, 34, 35, 36, 37]
    kokushi_toitsu = 0
    for i in kokushi_l:
        if tehai[i] >= 1:
            Sh_kokushi -= 1
        if kokushi_toitsu == 0 and tehai[i] >= 2:  #1,9、字牌の対子があれば1つだけシャンテン数が下がる
            kokushi_toitsu = 1
    Sh_kokushi -= kokushi_toitsu

    #七対子形
    Sh_chiitoi = 6  #ここから対子の数だけ引く
    haisyu = 0  #牌の種類
    for i in range(0, 38):
        if tehai[i] >= 1:
            haisyu += 1
            if tehai[i] >= 2:
                Sh_chiitoi -= 1
    if haisyu < 7:
        Sh_chiitoi += 7 - haisyu

    #4面子1雀頭形
    #tehaiを色ごとにハッシュ化
    manzu_hash = 0  #萬子部分のハッシュ値
    for i in range(1, 10):
        manzu_hash = manzu_hash * 5 + tehai[i]
    pinzu_hash = 0  #筒子部分のハッシュ値
    for i in range(11, 20):
        pinzu_hash = pinzu_hash * 5 + tehai[i]
    souzu_hash = 0  #索子部分のハッシュ値
    for i in range(21, 30):
        souzu_hash = souzu_hash * 5 + tehai[i]
    zihai_hash = 0  #字牌部分のハッシュ値
    for i in range(31, 38):
        zihai_hash = zihai_hash * 5 + tehai[i]

    #各ハッシュ値をキーにハッシュテーブルにある部分置換数t,uを取得
    t_manzu = []  #萬子部分の部分置換数tの配列
    u_manzu = []  #萬子部分の部分置換数uの配列
    for i in range(0, 5):
        t_manzu.append(int(hash_table[0][manzu_hash].split()[i]))
    for i in range(5, 10):
        u_manzu.append(int(hash_table[0][manzu_hash].split()[i]))
    t_pinzu = []  #筒子部分の部分置換数tの配列
    u_pinzu = []  #筒子部分の部分置換数uの配列
    for i in range(0, 5):
        t_pinzu.append(int(hash_table[0][pinzu_hash].split()[i]))
    for i in range(5, 10):
        u_pinzu.append(int(hash_table[0][pinzu_hash].split()[i]))
    t_souzu = []  #索子部分の部分置換数tの配列
    u_souzu = []  #索子部分の部分置換数uの配列
    for i in range(0, 5):
        t_souzu.append(int(hash_table[0][souzu_hash].split()[i]))
    for i in range(5, 10):
        u_souzu.append(int(hash_table[0][souzu_hash].split()[i]))
    t_zihai = []  #字牌部分の部分置換数tの配列
    u_zihai = []  #字牌部分の部分置換数uの配列
    for i in range(0, 5):
        t_zihai.append(int(hash_table[1][zihai_hash].split()[i]))
    for i in range(5, 10):
        u_zihai.append(int(hash_table[1][zihai_hash].split()[i]))

    t = [t_manzu, t_pinzu, t_souzu, t_zihai]
    u = [u_manzu, u_pinzu, u_souzu, u_zihai]

    #計算部分
    x = [[0 for m in range(0, 5)] for n in range(0, 4)]
    y = [[0 for m in range(0, 5)] for n in range(0, 4)]
    for m in range(0, 5):
        x[0][m] = t[0][m]
        y[0][m] = u[0][m]
    for n in range(1, 4):
        for m in range(0, 5):
            x_temp = 15
            y_temp = 15
            for l in range(0, m + 1):
                x_temp = min(x_temp, x[n - 1][l] + t[n][m - l])
                y_temp = min(
                    y_temp,
                    min(y[n - 1][l] + t[n][m - l], x[n - 1][l] + u[n][m - l]))
            x[n][m] = x_temp
            y[n][m] = y_temp
    Th_temp = 15
    for l in range(0, 5 - fuurosu):
        Th_temp = min(
            Th_temp,
            min(x[2][l] + u[3][(4 - fuurosu) - l],
                y[2][l] + t[3][(4 - fuurosu) - l]))
    Sh_normal = Th_temp - 1

    #最終的なシャンテン数
    Shanten_su = min(Sh_normal, Sh_kokushi, Sh_chiitoi)
    return Shanten_su
def new_yuukouhai_explore(shanten_suu, janshi, taku, kuikae_list, top4_list, janshi_list, bakyou_list):
    hash_table = taku.hash_table
    tehai = np.array(function.tehai_convert(janshi.tehai))
    danger_degree_list = danger_degree.create_danger_degree_list(janshi_list, taku, bakyou_list)
    #print(danger_degree_list)
    
    #ツモって来る牌に赤ドラは考慮しない
    yama = np.array(function.tehai_convert(function.akadora_convert(janshi.vertual_yama)[0]))    
    init_shanten_suu = shanten_suu
    #index_list = [0]*len(tehai)
    sum_list = [0]*len(tehai)
    pure_point_sum = [0]*len(tehai)
    pure_pure_point_sum = [0]*len(tehai)
    max_point = [0]*len(tehai)
    #mean_list = [0]*len(tehai)
    if init_shanten_suu >= 2:
        hai_list = top4_list
    else:
        hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    #print(hai_list)

    #hai_listからkuikae_listを削除
    temp_hai_list = hai_list.copy()
    for i in range(len(hai_list)):
        if temp_hai_list[i] in kuikae_list:
            hai_list.remove(temp_hai_list[i])

    #副露した時でアガリ役なしの場合
    if len(hai_list) == 0:
        #print("no_hai_list_error")
        return [0.001]*len(janshi.tehai), [0.001]*len(janshi.tehai), [0.001]*len(janshi.tehai), [0.001]*len(janshi.tehai), [0.001]*len(janshi.tehai), [0.001]*len(janshi.tehai)
    
    #バグ防止用
    for i in hai_list:
        sum_list[i] += 0.001
    
    #print(hai_list)
    if init_shanten_suu >= 2:
        itr = 20
    else:
        itr = 25

    for i in hai_list:
        for j in range(itr):
            count = 1.
            temp_janshi = copy.deepcopy(janshi)
            temp_yama = yama.copy()      
            temp_janshi.tehai.remove(function.hai_convert_reverse(i))
            temp_janshi.sutehai.append(function.hai_convert_reverse(i))
            #評価用の修正されたpoint, 普通の点数
            a, b, c = yuukouhai_explore(temp_yama, init_shanten_suu, count, hash_table, temp_janshi, taku , janshi_list, bakyou_list, danger_degree_list)
            #オーラス用max_pointの更新など
            if b > max_point[i]:
                max_point[i] = b
            pure_point_sum[i] += b
            pure_pure_point_sum[i] += c
                        
            #index_list[i] += 1
            sum_list[i] += a
        pure_pure_point_sum[i] /= max(init_shanten_suu + 1, 1)*itr


    normalized_index_list = np.array(sum_list)/np.sum(np.array(sum_list))
    normalized_list = np.zeros(len(janshi.tehai))
    sum_list_for_tehai_str = np.zeros(len(janshi.tehai))
    pure_point_mean = np.array(pure_point_sum)/float(itr)
    max_point_list = np.zeros(len(janshi.tehai))
    pure_point_mean_list = np.zeros(len(janshi.tehai))
    pure_point_sum_for_tehai_str = np.zeros(len(janshi.tehai))

    for i in range(len(janshi.tehai)):
        normalized_list[i] = normalized_index_list[function.hai_convert(janshi.tehai[i])]
        sum_list_for_tehai_str[i] = sum_list[function.hai_convert(janshi.tehai[i])]
        max_point_list[i] = max_point[function.hai_convert(janshi.tehai[i])]
        pure_point_mean_list[i] = pure_point_mean[function.hai_convert(janshi.tehai[i])]
        pure_point_sum_for_tehai_str[i] = pure_pure_point_sum[function.hai_convert(janshi.tehai[i])]

    mean_list_for_tehai_str = sum_list_for_tehai_str/float(itr)
   
    return normalized_list, sum_list_for_tehai_str, mean_list_for_tehai_str, max_point_list, pure_point_mean_list, pure_point_sum_for_tehai_str
def new_yuukouhai_explore(shanten_suu, janshi, taku):
    #print("aaaaaaaaaaaaaaaaaaaaa")
    global sum_list, pure_point_sum
    global janshi_global, yama_global, taku_global, shanten_suu_global, itr_global
    hash_table = taku.hash_table
    tehai = np.array(function.tehai_convert(janshi.tehai))

    #ツモって来る牌に赤ドラは考慮しない
    yama = np.array(
        function.tehai_convert(
            function.akadora_convert(janshi.vertual_yama)[0]))
    init_shanten_suu = shanten_suu
    #index_list = [0]*len(tehai)
    sum_list = [0] * len(tehai)
    pure_point_sum = [0] * len(tehai)
    print(len(sum_list))
    #mean_list = [0]*len(tehai)
    if shanten_suu >= 2:
        hai_list = find_yuukou_sutehai(janshi, init_shanten_suu, hash_table)
    #テンパイならシャンテン戻しも考える
    else:
        hai_list = function.tehai_convert3(janshi.tehai)

    #print(hai_list)
    #副露した時でアガリ役なしの場合
    if len(hai_list) == 0:
        #print("no_hai_list_error")
        return [0.001] * len(janshi.tehai), [0.001] * len(
            janshi.tehai), [0.001] * len(janshi.tehai)

    #バグ防止用
    for i in hai_list:
        sum_list[i] += 0.001

    #print(hai_list)
    if init_shanten_suu >= 2:
        itr = 25
    elif init_shanten_suu == 1:
        itr = 20
    else:
        itr = 15
    itr_global = itr

    janshi_global = janshi
    yama_global = yama
    taku_global = taku
    taku.hash_table = None
    shanten_suu_global = shanten_suu

    temp_list = [[hai_id, janshi, yama, taku, shanten_suu, itr]
                 for hai_id in reversed(hai_list)]
    p = Pool(multi.cpu_count())
    print(multi.cpu_count())
    print(hai_list)
    #print(time.time())
    p.starmap(temp_process, temp_list)
    #p.map(test_process, hai_list)
    p.close()

    taku.hash_table = hash_table

    for i in hai_list:
        print(i)
        for j in range(itr):
            count = 1.0
            temp_janshi = copy.deepcopy(janshi)
            #temp_tehai = tehai.copy()
            temp_yama = yama.copy()
            #temp_tehai[i] -= 1
            temp_janshi.tehai.remove(function.hai_convert_reverse(
                i))  # = function.tehai_convert_reverse(temp_tehai)
            temp_janshi.sutehai.append(function.hai_convert_reverse(i))
            if j == 0:
                init_shanten_suu = shanten_check_new.shanten_check(
                    temp_janshi, taku.hash_table)
            a, b = yuukouhai_explore(temp_yama, init_shanten_suu, count,
                                     hash_table, temp_janshi, taku)
            #index_list[i] += 1
            sum_list[i] += a
            pure_point_sum[i] += b
        #shanten_suu + 1で平均打点を割る
        pure_point_sum[i] /= max(init_shanten_suu + 1, 1) * itr
示例#10
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
示例#11
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
示例#12
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
示例#13
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]