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]
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]
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_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
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
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
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]