def run_game(self, map_settings: str, players: List[AbstractPlayer], player1_id: str, **kwargs): if isinstance(players[0], BotLadder): raise Exception("Player 1 cannot be a ladder bot!") if len(players) > 1 and isinstance(players[1], BotLadder): # host_only_args = ["save_replay_as", "rgb_render_config", "random_seed", "sc2_version"] # Port config portconfig = Portconfig() ports = [portconfig.shared + p for p in range(1, 8)] portconfig.shared = ports[0] # Not used portconfig.server = [ports[1], ports[2]] portconfig.players = [[ports[3], ports[4]], [ports[5], ports[6]]] self.ladder_player2_port = portconfig.players[1][0] # noinspection PyTypeChecker ladder_bot: BotLadder = players[1] opponent_id = player1_id # players[0].name result = asyncio.get_event_loop().run_until_complete( asyncio.gather( _host_game(map_settings, players, **kwargs, portconfig=portconfig), self.join_game(ladder_bot, False, portconfig, opponent_id) # ladder_bot.join_game(opponent_id, portconfig=portconfig) )) return result else: return run_game(map_settings, players, **kwargs)
def run_game(map_settings, players, **kwargs) -> Union[Result, List[Optional[Result]]]: """ Returns a single Result enum if the game was against the built-in computer. Returns a list of two Result enums if the game was "Human vs Bot" or "Bot vs Bot". """ if sum(isinstance(p, (Human, Bot)) for p in players) > 1: host_only_args = ["save_replay_as", "rgb_render_config", "random_seed", "sc2_version", "disable_fog"] join_kwargs = {k: v for k, v in kwargs.items() if k not in host_only_args} portconfig = Portconfig() async def run_host_and_join(): return await asyncio.gather( _host_game(map_settings, players, **kwargs, portconfig=portconfig), _join_game(players, **join_kwargs, portconfig=portconfig), return_exceptions=True ) result: List[Result] = asyncio.run(run_host_and_join()) assert isinstance(result, list) assert all(isinstance(r, Result) for r in result) else: result: Result = asyncio.run(_host_game(map_settings, players, **kwargs)) assert isinstance(result, Result) return result
async def run_match(controllers: List[Controller], match: GameMatch, close_ws=True): await _setup_host_game(controllers[0], **match.host_game_kwargs) # Setup portconfig beforehand, so all players use the same ports startport = None portconfig = None if match.needed_sc2_count > 1: if any(isinstance(player, BotProcess) for player in match.players): portconfig = Portconfig.contiguous_ports() # Most ladder bots generate their server and client ports as [s+2, s+3], [s+4, s+5] startport = portconfig.server[0] - 2 else: portconfig = Portconfig() proxies = [] coros = [] players_that_need_sc2 = filter(lambda lambda_player: lambda_player.needs_sc2, match.players) for i, player in enumerate(players_that_need_sc2): if isinstance(player, BotProcess): pport = portpicker.pick_unused_port() p = Proxy(controllers[i], player, pport, match.game_time_limit, match.realtime) proxies.append(p) coros.append(p.play_with_proxy(startport)) else: coros.append( play_from_websocket( controllers[i]._ws, player, match.realtime, portconfig, should_close=close_ws, game_time_limit=match.game_time_limit, ) ) async_results = await asyncio.gather(*coros, return_exceptions=True) if not isinstance(async_results, list): async_results = [async_results] for i, a in enumerate(async_results): if isinstance(a, Exception): logger.error(f"Exception[{a}] thrown by {[p for p in match.players if p.needs_sc2][i]}") return process_results(match.players, async_results)
def run_replay(ai, replay_path, realtime=False, observed_id=0): portconfig = Portconfig() assert os.path.isfile(replay_path), f"Replay does not exist at the given path: {replay_path}" assert os.path.isabs( replay_path ), f'Replay path has to be an absolute path, e.g. "C:/replays/my_replay.SC2Replay" but given path was "{replay_path}"' base_build, data_version = get_replay_version(replay_path) result = asyncio.get_event_loop().run_until_complete( _host_replay(replay_path, ai, realtime, portconfig, base_build, data_version, observed_id) ) return result
def run_ladder_game(bot): """Connect to the ladder server and run the game""" parser = argparse.ArgumentParser() parser.add_argument("--GamePort", type=int, nargs="?", help="Game port") parser.add_argument("--StartPort", type=int, nargs="?", help="Start port") parser.add_argument("--LadderServer", type=str, nargs="?", help="Ladder server") parser.add_argument("--ComputerOpponent", type=str, nargs="?", help="Computer opponent") parser.add_argument("--ComputerRace", type=str, nargs="?", help="Computer race") parser.add_argument("--ComputerDifficulty", type=str, nargs="?", help="Computer difficulty") args, _ = parser.parse_known_args() if args.LadderServer is None: host = "127.0.0.1" else: host = args.LadderServer host_port = args.GamePort lan_port = args.StartPort ports = [lan_port + p for p in range(1, 6)] portconfig = Portconfig() portconfig.shared = ports[0] portconfig.server = [ports[1], ports[2]] portconfig.players = [[ports[3], ports[4]]] game = join_ladder_game(host=host, port=host_port, players=[bot], realtime=False, portconfig=portconfig) result = asyncio.get_event_loop().run_until_complete(game) print(result)
def play_game(hostname, address, n_games, alive_event, req_kill_event, exc_queue, timeout, actor): # n_games: # 게임 인스턴스를 한번 실행해서 연속으로 몇 번이나 게임을 실행할 것인가? # - 너무 작으면, 게임 인스턴스를 자주 재시작해야하기 때문에 속도가 느려짐 # - 너무 크면, 예외 상황이 발생할 가능성이 높음 # sync_event: # host (게임 서버)와 join (클라이언트) 사이의 동기를 맞추기 위해 사용 # host가 learner에게 전달받은 대로 게임 세팅 설정한 뒤에 set을 해서, # join이 다음 단계를 진행할 수 있도록 함 sync_event = asyncio.Event() portconfig = Portconfig() context = zmq.Context() sock = context.socket(zmq.REQ) sock.RCVTIMEO = timeout # zmq 시간제한 설정ㄴ sock.connect(address) # task_dict & players: # 게임 세팅 관련변수, # host와 join이 동일한 reference를 가지고 있어야 함 #task_dict = dict(step_interval=self.args.step_interval) task_dict = dict(step_interval=actor.args.step_interval) players = [None, None] asyncio.get_event_loop().run_until_complete(asyncio.gather( Actor._host_game( hostname, sock, task_dict, players, sync_event, alive_event, req_kill_event, exc_queue, n_games=n_games, realtime=False, portconfig=portconfig ), Actor._join_game( task_dict, players, sync_event, alive_event, req_kill_event, exc_queue, n_games=n_games, realtime=False, portconfig=portconfig ) ))
def main(): parser = argparse.ArgumentParser() parser.add_argument("port_config") args = parser.parse_args() portconfig = Portconfig.from_json(args.port_config) player_config = [Bot(Race.Terran, None), Bot(Race.Zerg, bot2.Bot2())] gen = _join_game_iter(player_config, realtime=False, portconfig=portconfig) while True: r = next(gen) reload(bot2) player_config[0].ai = bot2.Bot2() gen.send(player_config)
def run_game(map_settings, players, **kwargs): if sum(isinstance(p, (Human, Bot)) for p in players) > 1: host_only_args = ["save_replay_as", "random_seed"] join_kwargs = { k: v for k, v in kwargs.items() if k not in host_only_args } portconfig = Portconfig() result = asyncio.get_event_loop().run_until_complete( asyncio.gather( _host_game(map_settings, players, **kwargs, portconfig=portconfig), _join_game(players, **join_kwargs, portconfig=portconfig))) else: result = asyncio.get_event_loop().run_until_complete( _host_game(map_settings, players, **kwargs)) return result
def main(): parser = argparse.ArgumentParser() parser.add_argument("port_config") args = parser.parse_args() portconfig = Portconfig.from_json(args.port_config) player_config = [ Bot(Race.Terran, bot1.Bot1()), Bot(Race.Zerg, None) ] gen = sc2.main._host_game_iter( sc2.maps.get("Abyssal Reef LE"), player_config, realtime=False, portconfig=portconfig ) while True: r = next(gen) reload(bot1) player_config[0].ai = bot1.Bot1() gen.send(player_config)