Example #1
0
    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()
Example #2
0
    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()