async def _host_game( hostname, sock, task_dict, players, aio_event, alive_evnet, req_kill_event, exc_queue, n_games, realtime=False, portconfig=None, save_replay_as=None, step_time_limit=None, game_time_limit=None, rgb_render_config=None, random_seed=None, ): async with SC2Process(render=rgb_render_config is not None) as server: try: for _ in range(n_games): # Learner에게 다음에 실행할 게임 세팅을 요청 sock.send_multipart([CommandType.REQ_TASK]) task_dict.update(pickle.loads(sock.recv_multipart()[0])) # 게임 세팅 설정 # !주의!: join쪽 task_dict, players와 동일한 인스턴스를 유지해야 하기 때문에, # 절대 여기서 새로 생성하지 말고 업데이트만 해야함, # 불가: players = [_Bot(), _Bot()], 가능 players[0] = _Bot(); players[1] = _Bot() step_interval = task_dict['step_interval'] players[0] = _Bot(Race.Terran, MyBot(step_interval, hostname, sock)) players[1] = _Bot(Race.Terran, OppBot()) # 게임 세팅이 완료되면 event를 set해서 join 쪽도 다음 과정을 진행하도록 함 aio_event.set() # 게임이 새로 시작했음을 부모 프로세스에 알림 alive_evnet.set() # 게임 시작 map_settings = sc2.maps.get(task_dict['game_map']) await server.ping() client = await _setup_host_game(server, map_settings, players, realtime, random_seed) result = await _play_game(players[0], client, realtime, portconfig, step_time_limit, game_time_limit, rgb_render_config) if save_replay_as is not None: await client.save_replay(save_replay_as) await client.leave() # await client.quit() # 게임 인스턴스 재시작을 위해 프로세스 종료하지 않음 except: # 예외가 발생하면 부모 프로세스에 전달 import traceback exc_queue.put(traceback.format_exc()) # n_games 만큼 게임을 반복했음을 부모 프로세스에 알림 # join에서 host를 죽이거나, host에서 join을 죽일 경우를 대비해서, # host와 join 양쪽에 req_kill_evnet를 set 해야함 # -> 어떤 경우에도 부모는 이 프로세스를 종료해야함을 알 수 있음 req_kill_event.set()
async def _host_game(hostname, sock, task_dict, players, aio_event, alive_evnet, req_kill_event, exc_queue, n_games, realtime=False, portconfig=None, save_replay_as=None, step_time_limit=None, game_time_limit=None, rgb_render_config=None, random_seed=None): async with SC2Process(render=rgb_render_config is not None) as server: try: for j in range(n_games): # Learner에게 다음에 실행할 게임 세팅을 요청 sock.send_multipart([CommandType.REQ_TASK]) tmp = sock.recv_multipart() task_dict.update(pickle.loads(tmp[0])) # 게임 세팅 설정 # !주의!: join쪽 task_dict, players와 동일한 인스턴스를 유지해야 하기 때문에, # 절대 여기서 새로 생성하지 말고 업데이트만 해야함, # 불가: players = [_Bot(), _Bot()], 가능 players[0] = _Bot(); players[1] = _Bot() step_interval = task_dict['step_interval'] # pool # set으로 중복 방지 # pool은 opp2bot 1개 + (배틀,밤까) 봇 1개 + 배틀 봇 1개 + 탱크 봇 1개 + 밴시 봇 1개 + 타 팀 봇(flash/magic) 6개 + pool 4개 = max 15개의 봇으로 구성 # pool = ["Opp2Bot", "OppBotBattle", "OppBotBattleNoRaven", \ # "OppBotTank", "OppBotBanshee", "OppBotFlash", "OppBotFlash", "OppBotFlashFast", "OppBotFlashFast", "OppBotMagic", "OppBotMagic"] pool = ["Opp2Bot", "OppBotBattle", "OppBotBattleNoRaven", \ "OppBotTank", "OppBotBanshee", "OppBotFlashNew", "OppBotFlashNewRaven", "OppBotFlashFast", "OppBotFlashFast", "OppBotMagic", "OppBotMagic"] for i in range(1, 4): model_path = pathlib.Path(__file__).parent / ( 'model' + str(i) + '.pt') if os.path.isfile(model_path): pool.append(str(i)) ''' win = pickle.loads(tmp[1]) rates = [] # 뽑을 확률 설정 probs = np.repeat(0.5 / len(pool), len(pool)) for p in pool: win_tmp = win[p] if len(win_tmp) > 10: win_tmp = win_tmp[-10:-1] if not win_tmp: # 비어있으면 => 게임 한판도 안했으면 rates.append(1 - 1 / len(pool)) else: rates.append(1 - np.mean(win_tmp)) for i, rate in enumerate(rates) : prob = (rate / np.sum(rates) / 2) probs[i] = probs[i] + prob bot_str = list(np.random.choice(pool, 1, False, probs))[0] players[0] = _Bot(Race.Terran, MyBot(step_interval, hostname, sock, bot_str)) ''' bot_str = list(np.random.choice(pool, 1))[0] players[0] = _Bot( Race.Terran, MyBot(step_interval, hostname, sock, bot_str)) if bot_str == "Opp2Bot": players[1] = _Bot(Race.Terran, Opp2Bot()) elif bot_str == "OppBotBattle": players[1] = _Bot(Race.Terran, OppBotBattle()) elif bot_str == "OppBotBattleNoRaven": players[1] = _Bot(Race.Terran, OppBotBattleNoRaven()) elif bot_str == "OppBotTank": players[1] = _Bot(Race.Terran, OppBotTank()) elif bot_str == "OppBotBanshee": players[1] = _Bot(Race.Terran, OppBotBanshee()) elif bot_str == "OppBotFlashNew": players[1] = _Bot(Race.Terran, OppBotFlashNew()) elif bot_str == "OppBotFlashNewRaven": players[1] = _Bot(Race.Terran, OppBotFlashNewRaven()) elif bot_str == "OppBotFlashFast": players[1] = _Bot(Race.Terran, OppBotFlashFast()) elif bot_str == "OppBotMagic": players[1] = _Bot(Race.Terran, OppBotMagic()) else: players[1] = _Bot( Race.Terran, MyBot(step_interval, hostname, None, None, bot_str)) # 게임 세팅이 완료되면 event를 set해서 join 쪽도 다음 과정을 진행하도록 함 aio_event.set() # 게임이 새로 시작했음을 부모 프로세스에 알림 alive_evnet.set() # 게임 시작 map_settings = sc2.maps.get(task_dict['game_map']) await server.ping() client = await _setup_host_game(server, map_settings, players, realtime, random_seed) result = await _play_game(players[0], client, realtime, portconfig, step_time_limit, game_time_limit, rgb_render_config) # Result.Defeat, Result.Tie, Result.Victory #if result == Result.Defeat : # self.win[bot_str].append(-1) #elif result == Result.Tie : # self.win[bot_str].append(0) #elif result == Result.Victory : # self.win[bot_str].append(1) # print(result) if save_replay_as is not None: await client.save_replay(save_replay_as) await client.leave() # await client.quit() # 게임 인스턴스 재시작을 위해 프로세스 종료하지 않음 except: # 예외가 발생하면 부모 프로세스에 전달 import traceback exc_queue.put(traceback.format_exc()) # n_games 만큼 게임을 반복했음을 부모 프로세스에 알림 # join에서 host를 죽이거나, host에서 join을 죽일 경우를 대비해서, # host와 join 양쪽에 req_kill_evnet를 set 해야함 # -> 어떤 경우에도 부모는 이 프로세스를 종료해야함을 알 수 있음 req_kill_event.set()