def run_match(): # 玩家1 try: name1, func1 = plr1_dir.get_player() except Exception as e: showerror('玩家1 %s' % type(e).__name__, str(e)) return # 玩家2 try: name2, func2 = plr2_dir.get_player() except Exception as e: showerror('玩家2 %s' % type(e).__name__, str(e)) return # 设置比赛场地显示 display._setup_grid((width_set.get() * 2, height_set.get())) display._setup_players((name1, name2)) # 进行比赛 match_result = match((func1, func2), (name1, name2), width_set.get(), height_set.get(), turns_set.get(), time_set.get()) display.load_match_result(match_result, False) # 比赛记录 output_dir = log_dir.path_var.get() if not output_dir: return os.makedirs(output_dir, exist_ok=1) with open(os.path.join(output_dir, '%s-VS-%s.pkl' % (name1, name2)), 'wb') as file: pickle.dump(match_result, file)
def run_match_inner(*args): for w in OP_WIDGETS: w['state'] = DISABLED match_result = match_core.match(*args) names = args[1] info.set(end_text(names, match_result['result'])) try: outputdir = log_dir.path_var.get() if outputdir: os.makedirs(outputdir, exist_ok=True) with open( os.path.join(outputdir, '%s-VS-%s.pkl' % names), 'wb') as file: pickle.dump(match_result, file) except Exception as e: showerror(type(e).__name__, str(e)) for w in OP_WIDGETS: try: w['state'] = ACTIVE except: w['state'] = NORMAL
def repeated_match(players, names, rounds, log_record=False, *args, **kwargs): ''' 双方进行多次比赛 params: players - 先后手玩家模块列表 names - 双方玩家名称 rounds - 比赛局数 log_record - 是否生成比赛记录文件,默认为否 *args, **kwargs - 比赛运行参数 return: 元组,包含比赛结果及统计 [0] - 比赛结果统计字典 0 - 先手玩家胜 1 - 后手玩家胜 None - 平局 [1] - 原始比赛结果列表 ''' # 初始化存储空间 clear_storage() # 总初始化函数 for i in range(2): try: players[i].init(match_core.STORAGE[i]) except: pass # 初始化统计变量 result_raw = [] result_stat = {0: 0, 1: 0, None: 0} # 运行多局比赛 for i in range(rounds): # 获取比赛记录 match_log = match(players, names, *args, **kwargs) # 统计结果 result = match_log['result'] result_raw.append(result) result_stat[result[0]] += 1 # 生成比赛记录 if log_record: log_name = 'log/%s-VS-%s_%s.zlog' % (*names, i) save_match_log(match_log, log_name) # 总总结函数 for i in range(2): try: players[i].summaryall(match_core.STORAGE[i]) except: pass # 返回结果 return result_stat, result_raw
def run_match_inner(*args): widget_off() # 开始比赛 global MATCH_LOG MATCH_LOG = match_core.match(*args) names = args[1] info.set(end_text(names, MATCH_LOG['result'])) widget_on()
def run_match(): # 玩家 name1, func1 = plr1.AI_NAME, plr1.AI_MODULE name2, func2 = plr2.AI_NAME, plr2.AI_MODULE # 更新比赛场次 match_index = MATCH_COUNT.get() if not match_index: for i in 0, 1: try: exec('func%d.init(match_core.STORAGE[%d])' % (i + 1, i)) except: pass MATCH_COUNT.set(match_index + 1) # 停用控件 widget_off() display.button1['state'] = DISABLED global MATCH_RUNNING MATCH_RUNNING = True # 设置比赛场地显示 display._setup_grid((width_set.get() * 2, height_set.get())) display._setup_players((name1, name2)) # 是否开启直播接口 if DISPLAY_MATCHING.get(): match_core.FRAME_FUNC = update_hook else: match_core.FRAME_FUNC = match_core.NULL # 进行比赛 names = (name1, name2) match_result = match_core.match((func1, func2), names, width_set.get(), height_set.get(), turns_set.get(), time_set.get()) MATCH_RUNNING = False display.load_match_result(match_result, False) # 比赛记录 global MATCH_LOG MATCH_LOG = match_result res = match_result['result'][0] if res is not None: WIN_COUNT[res] += 1 tk.title('%s vs %s (%d : %d)' % (*names, *WIN_COUNT)) # 启用控件 widget_on()
def run_match(): # 玩家1 try: name1, func1 = plr1_dir.get_player() except Exception as e: showerror('在读取玩家1代码时出错', str(e)) return # 玩家2 try: name2, func2 = plr2_dir.get_player() except Exception as e: showerror('在读取玩家2代码时出错', str(e)) return # 进行比赛 match_result = match(name1, func1, name2, func2, width_set.get(), height_set.get(), turns_set.get(), time_set.get()) display.load_match_result(match_result)
def load_compact_log(path): ''' 读取紧密比赛记录 params: path - 保存路径 ''' compact_log = load_match_log(path) # 读取参数 bot_plrs = list(map(gen_player_module, compact_log['traces'])) names = compact_log['players'] k, h = compact_log['size'] k //= 2 mturn = compact_log['maxturn'] mtime = compact_log['maxtime'] overrides = compact_log['init'] # 复原比赛 expand_log = match_core.match(bot_plrs, names, k, h, mturn, mtime, overrides) expand_log['result'] = compact_log['result'] for frame, tleft in zip(expand_log['log'], zip(*compact_log['timeleft'])): frame['timeleft'] = tleft
def worker(id, net, data_queue, save=False): EPS_START = 0.9 EPS_END = 0.2 EPS_DECAY = 5000 class player1: def load(self, stat, storage): storage['field_size'] = 0 if 'tensor' in storage: del storage['tensor'] def play(self, stat, storage): tensor, field_size = getFeatureMap(stat) reward = field_size - storage['field_size'] if 'tensor' in storage: data_queue.put( (storage['tensor'], storage['action'], tensor, reward)) storage['tensor'] = tensor storage['field_size'] = field_size if 'steps_done' in storage: storage['steps_done'] += 1 else: storage['steps_done'] = 1 #print(tensor.shape) sample = random.random() eps_threshold = EPS_END + (EPS_START - EPS_END) * \ math.exp(-1. * storage['steps_done'] / EPS_DECAY) #print('EPS: ', storage['steps_done'], eps_threshold) choices = ['l', 's', 'r'] if sample > eps_threshold: #print('Using Net') with torch.no_grad(): res = net(tensor).max(1)[1] ret = choices[res] else: ret = random.choice(['l', 'r', 's']) storage['action'] = ret #print(ret) return ret def summary(self, result, stat, storage): tensor, field_size = getFeatureMap(stat) eps_threshold = EPS_END + (EPS_START - EPS_END) * \ math.exp(-1. * storage['steps_done'] / EPS_DECAY) if id == 0: print('EPS: ', storage['steps_done'], eps_threshold, "Size: ", tensor[0][0].sum()) if result[0] is not None and result[1] >= 0: if result[0] == stat['log'][0]['me']['id'] - 1: reward = 0 else: reward = -0 data_queue.put( (storage['tensor'], storage['action'], None, reward)) class player2: def load(self, stat, storage): return p2.load(stat, storage) def play(self, stat, storage): return "r" return p2.play(stat, storage) gameCnt = 1 while True: t1 = pf() res = match((player1(), player2())) t2 = pf() if id == 0: print("Time: ", t2 - t1) print(gameCnt, ' Match Done') if save: save_match_log(res, 'saves/' + str(gameCnt % 100) + '.zlog') gameCnt += 1 if 'DEBUG_TRACEBACK' in dir(match): print(match.DEBUG_TRACEBACK) exit()
else: for plr in players: duels[plr] += 1 return res # 开始循环赛 for name1, func1 in players: for name2, func2 in players: # 跳过左右互搏 if name1 == name2: continue # 重复9次比赛并计入统计 for i in range(9): stat_(match(name1, func1, name2, func2, k=15, h=29)) # 最后一次输出log stat_(match_with_log(name1, func1, name2, func2, k=15, h=29)) # 输出统计结果 for plr in wins: print('%s:%d胜 %d负 %d平' % ( \ plr, \ wins[plr], \ loses[plr], \ duels[plr] ))
def process_task(data_queue, path, names, log_format, rounds, match_params): ''' 子进程执行两玩家多局对决 params: data_queue - 数据队列 path - 玩家模块所在路径 names - 玩家名称 log_format - 记录文件名格式 比赛记录将保存为log_format % (*names, index)路径 rounds - 单向比赛局数(双向进行) match_params - 比赛参数 ''' # 读取玩家 sys.path.append(path) players = [__import__(n) for n in names] # 双向比赛 win_counts = [0, 0] for i in 0, 1: # 初始化存储空间、局数统计 match_core.STORAGE = [{}, {}] # 第二次交换比赛 if i: players = players[::-1] names = names[::-1] win_counts = win_counts[::-1] # 总初始化函数 for i in range(2): try: players[i].init(match_core.STORAGE[i]) except: pass # 运行多局比赛 for i in range(rounds): # 进行比赛,获取记录 match_log = match_core.match(players, names, *match_params) # 生成比赛记录 log_name = log_format % (*names, i) match_interface.save_match_log(match_log, log_name) # 比赛结果传递至队列 result = match_log['result'] data_queue.put((names, result)) # 统计比赛结果,若胜利过半则跳出 if result[0] is not None: win_counts[result[0]] += 1 if win_counts[result[0]] > rounds: break # 总总结函数 for i in range(2): try: players[i].summaryall(match_core.STORAGE[i]) except: pass