def create_game( self, map_name, bot_difficulty=sc_pb.VeryEasy, bot_race=sc_common.Random, bot_first=False): """Create a game, one remote agent vs the specified bot. Args: map_name: The map to use. bot_difficulty: The difficulty of the bot to play against. bot_race: The race for the bot. bot_first: Whether the bot should be player 1 (else is player 2). """ self._reconnect() self._controller.ping() # Form the create game message. map_inst = maps.get(map_name) map_data = map_inst.data(self._run_config) if map_name not in self._saved_maps: self._controller.save_map(map_inst.path, map_data) self._saved_maps.add(map_name) create = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_data), disable_fog=False) # Set up for one bot, one agent. if not bot_first: create.player_setup.add(type=sc_pb.Participant) create.player_setup.add( type=sc_pb.Computer, race=bot_race, difficulty=bot_difficulty) if bot_first: create.player_setup.add(type=sc_pb.Participant) # Create the game. self._controller.create_game(create) self._disconnect()
def test_versions_create_game(self): run_config = run_configs.get() failures = [] for game_version in sorted(run_config.get_versions().keys()): try: log_center("starting create game: %s", game_version) with run_config.start(version=game_version, want_rgb=False) as controller: interface = sc_pb.InterfaceOptions() interface.raw = True interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 84 interface.feature_layer.resolution.y = 84 interface.feature_layer.minimap_resolution.x = 64 interface.feature_layer.minimap_resolution.y = 64 map_inst = maps.get("Simple64") create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Terran, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame(race=sc_common.Terran, options=interface) controller.create_game(create) controller.join_game(join) for _ in range(5): controller.step(16) controller.observe() log_center("success: %s", game_version) except: # pylint: disable=bare-except logging.exception("Failed") log_center("failure: %s", game_version) failures.append(game_version) self.assertEmpty(failures)
async def create_game(self, game_map, players, realtime, random_seed=None): assert isinstance(realtime, bool) req = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=str(game_map.relative_path)), realtime=realtime) if random_seed is not None: req.random_seed = random_seed for player in players: p = req.player_setup.add() p.type = player.type.value if isinstance(player, Computer): p.race = player.race.value p.difficulty = player.difficulty.value p.ai_build = player.ai_build.value logger.info("Creating new game") logger.info(f"Map: {game_map.name}") logger.info(f"Players: {', '.join(str(p) for p in players)}") result = await self._execute(create_game=req) return result
def _launch(self, interface, player_setup): agent_race, bot_race, difficulty = player_setup # changed by mindgameSC2 if self.game_version is not None: self._sc2_procs = [self._run_config.start(game_version=self.game_version)] else: self._sc2_procs = [self._run_config.start()] self._controllers = [p.controller for p in self._sc2_procs] # Create the game. create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=self._map.path, map_data=self._run_config.map_data(self._map.path))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=races[bot_race], difficulty=difficulties[difficulty]) create.random_seed = 5 # create.disable_fog = True self._controllers[0].create_game(create) join = sc_pb.RequestJoinGame(race=races[agent_race], options=interface) self._controllers[0].join_game(join)
async def create_game(self, game_map, players, realtime, random_seed=None): assert isinstance(realtime, bool) # hspark: start # if type(game_map) is str: # 기존플랫폼은 반드시 StarCraftII/Maps 폴더에 지도가 있어야 하지만, # 문자열로 직접 경로를 입력해도 처리 할 수 있도록 수정 import os from collections import namedtuple gm = namedtuple('game_map', 'relative_path, name') if game_map.endswith('.SC2Map'): game_map = gm(os.path.abspath(game_map), os.path.basename(game_map).split('.')[0]) else: game_map = gm( os.path.abspath(game_map) + '.SC2Map', os.path.basename(game_map)) # hspark: end # req = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=str(game_map.relative_path)), realtime=realtime) if random_seed is not None: req.random_seed = random_seed for player in players: p = req.player_setup.add() p.type = player.type.value if isinstance(player, Computer): p.race = player.race.value p.difficulty = player.difficulty.value p.ai_build = player.ai_build.value logger.info("Creating new game") logger.info(f"Map: {game_map.name}") logger.info(f"Players: {', '.join(str(p) for p in players)}") result = await self._execute(create_game=req) return result
def _launch_sp(self, map_inst, interface): self._sc2_procs = [self._run_config.start()] self._controllers = [p.controller for p in self._sc2_procs] # Create the game. create = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap( map_path=map_inst.path, map_data=map_inst.data(self._run_config)), disable_fog=self._disable_fog) agent_race = Race.random for p in self._players: if isinstance(p, Agent): create.player_setup.add(type=sc_pb.Participant) agent_race = p.race else: create.player_setup.add(type=sc_pb.Computer, race=p.race, difficulty=p.difficulty) if self._random_seed is not None: create.random_seed = self._random_seed self._controllers[0].create_game(create) join = sc_pb.RequestJoinGame(race=agent_race, options=interface) self._controllers[0].join_game(join)
def test_observer(self): run_config = run_configs.get() map_inst = maps.get("Simple64") with run_config.start(want_rgb=False) as controller: create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.VeryEasy) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.VeryHard) create.player_setup.add(type=sc_pb.Observer) controller.create_game(create) join = sc_pb.RequestJoinGame( options=sc_pb.InterfaceOptions(), # cheap observations observed_player_id=0) controller.join_game(join) outcome = False for _ in range(60 * 60): # 60 minutes should be plenty. controller.step(16) obs = controller.observe() if obs.player_result: print( "Outcome after %s steps (%0.1f game minutes):" % (obs.observation.game_loop, obs.observation.game_loop / (16 * 60))) for r in obs.player_result: print("Player %s: %s" % (r.player_id, sc_pb.Result.Name(r.result))) outcome = True break self.assertTrue(outcome)
def create_game(self, map_name): """Create a game for the agents to join. Args: map_name: The map to use. """ map_inst = maps.get(map_name) map_data = map_inst.data(self._run_config) if map_name not in self._saved_maps: for controller in self._controllers: controller.save_map(map_inst.path, map_data) self._saved_maps.add(map_name) # Form the create game message. create = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=map_inst.path), disable_fog=False) # Set up for two agents. for _ in range(self._num_agents): create.player_setup.add(type=sc_pb.Participant) # Create the game. self._controllers[0].create_game(create)
def _launch(self): self._run_config = run_configs.get() self._map = maps.get(self.map_name) # Setting up the interface self.interface = sc_pb.InterfaceOptions( raw = True, # raw, feature-level data score = True) self._sc2_proc = self._run_config.start(game_version=self.game_version, window_size=self.window_size) self.controller = self._sc2_proc.controller # Create the game. create = sc_pb.RequestCreateGame(realtime = False, random_seed = self.seed, local_map=sc_pb.LocalMap(map_path=self._map.path, map_data=self._run_config.map_data(self._map.path))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=races[self._bot_race], difficulty=difficulties[self.difficulty]) self.controller.create_game(create) join = sc_pb.RequestJoinGame(race=races[self._agent_race], options=self.interface) self.controller.join_game(join)
def test_load_random_map(self): """Test loading a few random maps.""" all_maps = maps.get_maps() run_config = run_configs.get() with run_config.start() as controller: # Test only a few random maps when run locally to minimize time. count = 5 map_sample = random.sample(all_maps.items(), min(count, len(all_maps))) for _, map_class in sorted(map_sample): m = map_class() logging.info("Loading map: %s", m.name) create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=m.path, map_data=m.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_pb.Random, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame( race=sc_pb.Random, options=sc_pb.InterfaceOptions(raw=True)) controller.create_game(create) controller.join_game(join) # Verify it has the right mods and isn't running into licensing issues. info = controller.game_info() logging.info("Mods for %s: %s", m.name, info.mod_names) self.assertIn("Mods/Void.SC2Mod", info.mod_names) self.assertIn("Mods/VoidMulti.SC2Mod", info.mod_names) # Verify it can be played without making actions. for _ in range(3): controller.step() controller.observe()
def human(): """Run a host which expects one player to connect remotely.""" run_config = run_configs.get() map_inst = maps.get(FLAGS.map) if not FLAGS.rgb_screen_size or not FLAGS.rgb_minimap_size: logging.info( "Use --rgb_screen_size and --rgb_minimap_size if you want rgb " "observations.") ports = portspicker.pick_contiguous_unused_ports(4) # 2 * num_players host_proc = run_config.start(extra_ports=ports, host=FLAGS.host, timeout_seconds=300, window_loc=(50, 50)) client_proc = run_config.start(extra_ports=ports, host=FLAGS.host, connect=False, window_loc=(700, 50)) create = sc_pb.RequestCreateGame( realtime=FLAGS.realtime, local_map=sc_pb.LocalMap(map_path=map_inst.path)) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Participant) controller = host_proc.controller controller.save_map(map_inst.path, map_inst.data(run_config)) controller.create_game(create) print("-" * 80) print("Join host: agent_remote --map %s --host %s --host_port %s " "--lan_port %s" % (FLAGS.map, FLAGS.host, client_proc.port, ports[0])) print("-" * 80) join = sc_pb.RequestJoinGame() join.shared_port = 0 # unused join.server_ports.game_port = ports.pop(0) join.server_ports.base_port = ports.pop(0) join.client_ports.add(game_port=ports.pop(0), base_port=ports.pop(0)) join.race = sc2_env.Race[FLAGS.user_race] if FLAGS.render: join.options.raw = True join.options.score = True if FLAGS.feature_screen_size and FLAGS.feature_minimap_size: fl = join.options.feature_layer fl.width = 24 FLAGS.feature_screen_size.assign_to(fl.resolution) FLAGS.feature_minimap_size.assign_to(fl.minimap_resolution) if FLAGS.rgb_screen_size and FLAGS.rgb_minimap_size: FLAGS.rgb_screen_size.assign_to(join.options.render.resolution) FLAGS.rgb_minimap_size.assign_to( join.options.render.minimap_resolution) controller.join_game(join) if FLAGS.render: renderer = renderer_human.RendererHuman(fps=FLAGS.fps, render_feature_grid=False) renderer.run(run_configs.get(), controller, max_episodes=1) else: # Still step forward so the Mac/Windows renderer works. try: while True: frame_start_time = time.time() if not FLAGS.realtime: controller.step() obs = controller.observe() if obs.player_result: break time.sleep( max(0, frame_start_time - time.time() + 1 / FLAGS.fps)) except KeyboardInterrupt: pass for p in [host_proc, client_proc]: p.close() portspicker.return_ports(ports)
def start_game(self, show_cloaked=True, disable_fog=False, players=2): """Start a multiplayer game with options.""" self._disable_fog = disable_fog run_config = run_configs.get() self._parallel = run_parallel.RunParallel() # Needed for multiplayer. map_inst = maps.get("Flat64") self._map_data = map_inst.data(run_config) self._ports = portspicker.pick_unused_ports(4) if players == 2 else [] self._sc2_procs = [ run_config.start(extra_ports=self._ports, want_rgb=False) for _ in range(players) ] self._controllers = [p.controller for p in self._sc2_procs] if players == 2: for c in self._controllers: # Serial due to a race condition on Windows. c.save_map(map_inst.path, self._map_data) self._interface = sc_pb.InterfaceOptions() self._interface.raw = True self._interface.raw_crop_to_playable_area = True self._interface.show_cloaked = show_cloaked self._interface.score = False self._interface.feature_layer.width = 24 self._interface.feature_layer.resolution.x = 64 self._interface.feature_layer.resolution.y = 64 self._interface.feature_layer.minimap_resolution.x = 64 self._interface.feature_layer.minimap_resolution.y = 64 create = sc_pb.RequestCreateGame( random_seed=1, disable_fog=self._disable_fog, local_map=sc_pb.LocalMap(map_path=map_inst.path)) for _ in range(players): create.player_setup.add(type=sc_pb.Participant) if players == 1: create.local_map.map_data = self._map_data create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame(race=sc_common.Protoss, options=self._interface) if players == 2: join.shared_port = 0 # unused join.server_ports.game_port = self._ports[0] join.server_ports.base_port = self._ports[1] join.client_ports.add(game_port=self._ports[2], base_port=self._ports[3]) self._controllers[0].create_game(create) self._parallel.run((c.join_game, join) for c in self._controllers) self._info = self._controllers[0].game_info() self._features = features.features_from_game_info(self._info, use_raw_units=True) self._map_size = point.Point.build(self._info.start_raw.map_size) print("Map size:", self._map_size) self.in_game = True self.step() # Get into the game properly.
def __init__(self, # pylint: disable=invalid-name _only_use_kwargs=None, map_name=None, screen_size_px=(64, 64), minimap_size_px=(64, 64), camera_width_world_units=None, discount=1., visualize=False, agent_race=None, bot_race=None, difficulty=None, step_mul=None, save_replay_steps=0, replay_dir=None, game_steps_per_episode=None, score_index=None, score_multiplier=None): """Create a SC2 Env. Args: _only_use_kwargs: Don't pass args, only kwargs. map_name: Name of a SC2 map. Run bin/map_list to get the full list of known maps. Alternatively, pass a Map instance. Take a look at the docs in maps/README.md for more information on available maps. screen_size_px: The size of your screen output in pixels. minimap_size_px: The size of your minimap output in pixels. camera_width_world_units: The width of your screen in world units. If your screen_size_px=(64, 48) and camera_width is 24, then each px represents 24 / 64 = 0.375 world units in each of x and y. It'll then represent a camera of size (24, 0.375 * 48) = (24, 18) world units. discount: Returned as part of the observation. visualize: Whether to pop up a window showing the camera and feature layers. This won't work without access to a window manager. agent_race: One of P,T,Z,R default random. This is the race you control. bot_race: One of P,T,Z,R default random. This is the race controlled by the built-in bot. difficulty: One of 1-9,A. How strong should the bot be? step_mul: How many game steps per agent step (action/observation). None means use the map default. save_replay_steps: How many game steps to wait before saving a replay. Default of 0 means don't save replays. replay_dir: Directory to save replays to. Required with save_replay_steps. game_steps_per_episode: Game steps per episode, independent of the step_mul. 0 means no limit. None means use the map default. score_index: -1 means use the win/loss reward, >=0 is the index into the score_cumulative with 0 being the curriculum score. None means use the map default. score_multiplier: How much to multiply the score by. Useful for negating. Raises: ValueError: if the agent_race, bot_race or difficulty are invalid. """ # Make the destructor happy. self._renderer_human = None self._controller = None self._sc2_proc = None if _only_use_kwargs: raise ValueError("All arguments must be passed as keyword arguments.") if save_replay_steps and not replay_dir: raise ValueError("Missing replay_dir") if agent_race and agent_race not in races: raise ValueError("Bad agent_race args") if bot_race and bot_race not in races: raise ValueError("Bad bot_race args") if difficulty and str(difficulty) not in difficulties: raise ValueError("Bad difficulty") self._map = maps.get(map_name) self._discount = discount self._step_mul = step_mul or self._map.step_mul self._save_replay_steps = save_replay_steps self._replay_dir = replay_dir self._total_steps = 0 if score_index is None: self._score_index = self._map.score_index else: self._score_index = score_index if score_multiplier is None: self._score_multiplier = self._map.score_multiplier else: self._score_multiplier = score_multiplier self._last_score = None self._episode_length = (game_steps_per_episode or self._map.game_steps_per_episode) self._episode_steps = 0 self._run_config = run_configs.get() self._sc2_proc = self._run_config.start() self._controller = self._sc2_proc.controller screen_size_px = point.Point(*screen_size_px) minimap_size_px = point.Point(*minimap_size_px) interface = sc_pb.InterfaceOptions( raw=visualize, score=True, feature_layer=sc_pb.SpatialCameraSetup( width=camera_width_world_units or 24)) screen_size_px.assign_to(interface.feature_layer.resolution) minimap_size_px.assign_to(interface.feature_layer.minimap_resolution) create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=self._map.path, map_data=self._map.data(self._run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=races[bot_race or "R"], difficulty=difficulties[difficulty or "1"]) join = sc_pb.RequestJoinGame(race=races[agent_race or "R"], options=interface) self._controller.create_game(create) self._controller.join_game(join) game_info = self._controller.game_info() static_data = self._controller.data() self._features = features.Features(game_info) if visualize: self._renderer_human = renderer_human.RendererHuman() self._renderer_human.init(game_info, static_data) self._episode_count = 0 self._obs = None self._state = environment.StepType.LAST # Want to jump to `reset`. logging.info("Environment is ready.")
def server(): """Run a host which expects one player to connect remotely.""" run_config = run_configs.get() map_inst = maps.get(FLAGS.map) if not FLAGS.rgb_screen_size or not FLAGS.rgb_minimap_size: logging.info( "Use --rgb_screen_size and --rgb_minimap_size if you want rgb " "observations.") ports = [FLAGS.port0, FLAGS.port1, FLAGS.port2, FLAGS.port3, FLAGS.port4] if not all(portpicker.is_port_free(p) for p in ports): sys.exit("Need 5 free ports after the config port.") proc = None tcp_conn = None try: proc = run_config.start(extra_ports=ports[1:], timeout_seconds=300, host=FLAGS.host, window_loc=(50, 50)) tcp_port = ports[0] settings = { "remote": False, "game_version": proc.version.game_version, "realtime": FLAGS.realtime, "map_name": map_inst.name, "map_path": map_inst.path, "map_data": map_inst.data(run_config), "ports": { "server": { "game": ports[1], "base": ports[2] }, "client": { "game": ports[3], "base": ports[4] }, } } create = sc_pb.RequestCreateGame( realtime=settings["realtime"], local_map=sc_pb.LocalMap(map_path=settings["map_path"]), disable_fog=FLAGS.disable_fog) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Participant) controller = proc.controller controller.save_map(settings["map_path"], settings["map_data"]) controller.create_game(create) print("-" * 80) print("Join: agent_vs_agent --host %s --config_port %s" % (proc.host, tcp_port)) print("-" * 80) tcp_conn = lan_sc2_env.tcp_server( lan_sc2_env.Addr(proc.host, tcp_port), settings) join = sc_pb.RequestJoinGame() join.shared_port = 0 # unused join.server_ports.game_port = settings["ports"]["server"]["game"] join.server_ports.base_port = settings["ports"]["server"]["base"] join.client_ports.add(game_port=settings["ports"]["client"]["game"], base_port=settings["ports"]["client"]["base"]) join.race = sc2_env.Race[FLAGS.agent_race] join.options.raw = True join.options.score = True if FLAGS.feature_screen_size and FLAGS.feature_minimap_size: fl = join.options.feature_layer fl.width = 24 FLAGS.feature_screen_size.assign_to(fl.resolution) FLAGS.feature_minimap_size.assign_to(fl.minimap_resolution) if FLAGS.rgb_screen_size and FLAGS.rgb_minimap_size: FLAGS.rgb_screen_size.assign_to(join.options.render.resolution) FLAGS.rgb_minimap_size.assign_to( join.options.render.minimap_resolution) controller.join_game(join) with lan_server_sc2_env.LanServerSC2Env( race=sc2_env.Race[FLAGS.agent_race], step_mul=FLAGS.step_mul, agent_interface_format=sc2_env.parse_agent_interface_format( feature_screen=FLAGS.feature_screen_size, feature_minimap=FLAGS.feature_minimap_size, rgb_screen=FLAGS.rgb_screen_size, rgb_minimap=FLAGS.rgb_minimap_size, action_space=FLAGS.action_space, use_feature_units=FLAGS.use_feature_units), visualize=False, controller=controller, map_name=FLAGS.map) as env: agent_module, agent_name = FLAGS.agent.rsplit(".", 1) agent_cls = getattr(importlib.import_module(agent_module), agent_name) agent_kwargs = {} if FLAGS.agent_config: agent_kwargs['config_path'] = FLAGS.agent_config agents = [agent_cls(**agent_kwargs)] try: run_loop(agents, env, FLAGS.max_steps) except lan_server_sc2_env.RestartException: pass if FLAGS.save_replay: env.save_replay(agent_cls.__name__) finally: if tcp_conn: tcp_conn.close() if proc: proc.close()
def test_render(self): interface = sc_pb.InterfaceOptions() interface.raw = True interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 84 interface.feature_layer.resolution.y = 84 interface.feature_layer.minimap_resolution.x = 64 interface.feature_layer.minimap_resolution.y = 64 interface.feature_layer.crop_to_playable_area = True interface.feature_layer.allow_cheating_layers = True interface.render.resolution.x = 256 interface.render.resolution.y = 256 interface.render.minimap_resolution.x = 128 interface.render.minimap_resolution.y = 128 def or_zeros(layer, size): if layer is not None: return layer.astype(np.int32, copy=False) else: return np.zeros((size.y, size.x), dtype=np.int32) run_config = run_configs.get() with run_config.start() as controller: map_inst = maps.get("Simple64") create = sc_pb.RequestCreateGame( realtime=False, disable_fog=False, local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame(race=sc_common.Random, options=interface) controller.create_game(create) controller.join_game(join) game_info = controller.game_info() self.assertEqual(interface.raw, game_info.options.raw) self.assertEqual(interface.feature_layer, game_info.options.feature_layer) # Can fail if rendering is disabled. self.assertEqual(interface.render, game_info.options.render) for _ in range(50): controller.step(8) observation = controller.observe() obs = observation.observation rgb_screen = features.Feature.unpack_rgb_image( obs.render_data.map) rgb_minimap = features.Feature.unpack_rgb_image( obs.render_data.minimap) fl_screen = np.stack([ or_zeros(f.unpack(obs), interface.feature_layer.resolution) for f in features.SCREEN_FEATURES ]) fl_minimap = np.stack([ or_zeros(f.unpack(obs), interface.feature_layer.minimap_resolution) for f in features.MINIMAP_FEATURES ]) # Right shapes. self.assertEqual(rgb_screen.shape, (256, 256, 3)) self.assertEqual(rgb_minimap.shape, (128, 128, 3)) self.assertEqual(fl_screen.shape, (len(features.SCREEN_FEATURES), 84, 84)) self.assertEqual(fl_minimap.shape, (len(features.MINIMAP_FEATURES), 64, 64)) # Not all black. self.assertTrue(rgb_screen.any()) self.assertTrue(rgb_minimap.any()) self.assertTrue(fl_screen.any()) self.assertTrue(fl_minimap.any()) if observation.player_result: break
def _create_join(self): """Create the game, and join it.""" map_inst = random.choice(self._maps) self._map_name = map_inst.name self._step_mul = max(1, self._default_step_mul or map_inst.step_mul) self._score_index = get_default(self._default_score_index, map_inst.score_index) self._score_multiplier = get_default(self._default_score_multiplier, map_inst.score_multiplier) self._episode_length = get_default(self._default_episode_length, map_inst.game_steps_per_episode) if self._episode_length <= 0 or self._episode_length > MAX_STEP_COUNT: self._episode_length = MAX_STEP_COUNT # Create the game. Set the first instance as the host. create = sc_pb.RequestCreateGame(disable_fog=self._disable_fog, realtime=self._realtime) if self._battle_net_map: create.battlenet_map_name = map_inst.battle_net else: create.local_map.map_path = map_inst.path map_data = map_inst.data(self._run_config) if self._num_agents == 1: create.local_map.map_data = map_data else: # Save the maps so they can access it. Don't do it in parallel since SC2 # doesn't respect tmpdir on windows, which leads to a race condition: # https://github.com/Blizzard/s2client-proto/issues/102 for c in self._controllers: c.save_map(map_inst.path, map_data) if self._random_seed is not None: create.random_seed = self._random_seed for p in self._players: if isinstance(p, Agent): create.player_setup.add(type=sc_pb.Participant) else: create.player_setup.add(type=sc_pb.Computer, race=random.choice(p.race), difficulty=p.difficulty, ai_build=random.choice(p.build)) self._controllers[0].create_game(create) # Create the join requests. agent_players = [p for p in self._players if isinstance(p, Agent)] sanitized_names = crop_and_deduplicate_names(p.name for p in agent_players) join_reqs = [] for p, name, interface in zip(agent_players, sanitized_names, self._interface_options): join = sc_pb.RequestJoinGame(options=interface) join.race = random.choice(p.race) join.player_name = name if self._ports: join.shared_port = 0 # unused join.server_ports.game_port = self._ports[0] join.server_ports.base_port = self._ports[1] for i in range(self._num_agents - 1): join.client_ports.add(game_port=self._ports[i * 2 + 2], base_port=self._ports[i * 2 + 3]) join_reqs.append(join) # Join the game. This must be run in parallel because Join is a blocking # call to the game that waits until all clients have joined. self._parallel.run((c.join_game, join) for c, join in zip(self._controllers, join_reqs)) self._game_info = self._parallel.run(c.game_info for c in self._controllers) for g, interface in zip(self._game_info, self._interface_options): if g.options.render != interface.render: logging.warning( "Actual interface options don't match requested options:\n" "Requested:\n%s\n\nActual:\n%s", interface, g.options) self._features = [ features.features_from_game_info(game_info=g, agent_interface_format=aif, map_name=self._map_name) for g, aif in zip(self._game_info, self._interface_formats) ]
def main(unused_argv): interface = sc_pb.InterfaceOptions() interface.raw = True interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 84 interface.feature_layer.resolution.y = 84 interface.feature_layer.minimap_resolution.x = 64 interface.feature_layer.minimap_resolution.y = 64 timeline = [] start = time.time() run_config = run_configs.get() proc = run_config.start(want_rgb=interface.HasField("render")) process = psutil.Process(proc.pid) episode = 0 def add(s): cpu = process.cpu_times().user mem = process.memory_info().rss / 2**20 # In Mb step = Timestep(episode, time.time() - start, cpu, mem, s) print(step) timeline.append(step) if mem > FLAGS.mem_limit: raise MemoryException("%s Mb mem limit exceeded" % FLAGS.mem_limit) try: add("Started process") controller = proc.controller map_inst = maps.get("Simple64") create = sc_pb.RequestCreateGame( realtime=False, disable_fog=False, random_seed=1, local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Protoss, difficulty=sc_pb.CheatInsane) join = sc_pb.RequestJoinGame(race=sc_common.Protoss, options=interface) controller.create_game(create) add("Created game") controller.join_game(join) episode += 1 add("Joined game") for _ in range(FLAGS.episodes): for i in range(2000): controller.step(16) obs = controller.observe() if obs.player_result: add("Lost on step %s" % i) break if i > 0 and i % 100 == 0: add("Step %s" % i) controller.restart() episode += 1 add("Restarted") add("Done") except KeyboardInterrupt: pass except (MemoryException, protocol.ConnectionError) as e: print(e) finally: proc.close() print("Timeline:") for t in timeline: print(t)
def _launch(self): """Launch the StarCraft II game.""" self._run_config = run_configs.get() _map = maps.get(self.map_name) # Setting up the interface interface_options = sc_pb.InterfaceOptions(raw=True, score=False) self._sc2_proc = self._run_config.start(game_version=self.game_version, window_size=self.window_size) self._controller = self._sc2_proc.controller # HSPARK: 수정 시작 try: # self._run_config.data_dir = 'C:/Program Files (x86)/StarCraft II' self._run_config.map_data(_map.path) except FileNotFoundError: import os from pathlib import Path self._run_config.data_dir = Path( os.getcwd()) / 'smac' / 'env' / 'starcraft2' # HSPARK: 수정 종료 # Request to create the game create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=_map.path, map_data=self._run_config.map_data(_map.path)), realtime=False, random_seed=self._seed) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=races[self._bot_race], difficulty=difficulties[self.difficulty]) self._controller.create_game(create) join = sc_pb.RequestJoinGame(race=races[self._agent_race], options=interface_options) self._controller.join_game(join) game_info = self._controller.game_info() map_info = game_info.start_raw map_play_area_min = map_info.playable_area.p0 map_play_area_max = map_info.playable_area.p1 self.max_distance_x = map_play_area_max.x - map_play_area_min.x self.max_distance_y = map_play_area_max.y - map_play_area_min.y self.map_x = map_info.map_size.x self.map_y = map_info.map_size.y # HSPARK: 수정시작 # self.terrain_height = np.flip( # np.transpose(np.array(list(map_info.terrain_height.data)) # .reshape(self.map_x, self.map_y)), 1) / 255 # self.pathing_grid = np.flip( # np.transpose(np.array(list(map_info.pathing_grid.data)) # .reshape(self.map_x, self.map_y)), 1) / 255 self.terrain_height = np.flip( np.transpose( np.frombuffer( map_info.terrain_height.data, dtype=np.uint8).reshape( self.map_x, self.map_y)), 1) / 255 self.pathing_grid = np.flip( np.transpose( np.unpackbits( # 8비트 uint 형을 비트 단위로 풀어냄 1 bit --> 1 byte np.frombuffer(map_info.pathing_grid.data, dtype=np.uint8)).reshape( self.map_x, self.map_y)), 1) self.pathing_grid = 1 - self.pathing_grid
def run(config, agentCallBack, lobbyTimeout=c.DEFAULT_TIMEOUT, debug=False): """PURPOSE: start a starcraft2 process using the defined the config parameters""" FLAGS(sys.argv) # ignore pysc2 command-line handling (eww) log = protocol.logging.logging log.disable(log.CRITICAL) # disable pysc2 logging thisPlayer = config.whoAmI() createReq = sc_pb.RequestCreateGame( # used to advance to "Init Game" state, when hosting realtime=config.realtime, disable_fog=config.fogDisabled, random_seed=int(now( )), # a game is created using the current second timestamp as the seed local_map=sc_pb.LocalMap(map_path=config.mapLocalPath, map_data=config.mapData)) for player in config.players: reqPlayer = createReq.player_setup.add( ) # add new player; get link to settings playerObj = PlayerPreGame(player) if playerObj.isComputer: reqPlayer.difficulty = playerObj.difficulty.gameValue() reqPlayer.type = t.PlayerControls(playerObj.control).gameValue() reqPlayer.race = playerObj.selectedRace.gameValue() interface = sc_pb.InterfaceOptions() raw, score, feature, rendered = config.interfaces interface.raw = raw # whether raw data is reported in observations interface.score = score # whether score data is reported in observations interface.feature_layer.width = 24 #interface.feature_layer.resolution = #interface.feature_layer.minimap_resolution = joinReq = sc_pb.RequestJoinGame( options=interface) # SC2APIProtocol.RequestJoinGame joinReq.race = thisPlayer.selectedRace.gameValue( ) # update joinGame request as necessary # TODO -- allow host player to be an observer, not just a player w/ race gameP, baseP, sharedP = config.ports if config.isMultiplayer: joinReq.server_ports.game_port = gameP joinReq.server_ports.base_port = baseP joinReq.shared_port = sharedP for slaveGP, slaveBP in config.slavePorts: joinReq.client_ports.add(game_port=slaveGP, base_port=slaveBP) if debug: print("Starcraft2 game process is launching (fullscreen=%s)." % (config.fullscreen)) controller = None # the object that manages the application process finalResult = rh.playerSurrendered( config ) # default to this player losing if somehow a result wasn't acquired normally replayData = "" # complete raw replay data for the match with config.launchApp(fullScreen=config.fullscreen) as controller: try: getGameState = controller.observe # function that observes what's changed since the prior gameloop(s) if debug: print("Starcraft2 application is live. (%s)" % (controller.status)) # status: launched controller.create_game(createReq) if debug: print( "Starcraft2 is waiting for %d player(s) to join. (%s)" % (config.numAgents, controller.status)) # status: init_game playerID = controller.join_game( joinReq).player_id # SC2APIProtocol.RequestJoinGame config.updateID(playerID) print("[HOSTGAME] joined match as %s" % (thisPlayer)) startWaitTime = now() knownPlayers = [] numExpectedPlayers = config.numGameClients # + len(bots) : bots don't need to join; they're run by the host process automatically while len(knownPlayers) < numExpectedPlayers: elapsed = now() - startWaitTime if elapsed > lobbyTimeout: # wait for additional players to join raise c.TimeoutExceeded("timed out after waiting for players to "\ "join for waiting %.1f > %s seconds!"%(elapsed, lobbyTimeout)) ginfo = controller.game_info( ) # SC2APIProtocol.ResponseGameInfo object # map_name # mod_names # local_map_path # player_info # start_raw # options numCurrentPlayers = len(ginfo.player_info) if numCurrentPlayers == len(knownPlayers): continue # no new players for pInfo in ginfo.player_info: # parse ResponseGameInfo.player_info to validate player information (SC2APIProtocol.PlayerInfo) against the specified configuration pID = pInfo.player_id if pID in knownPlayers: continue # player joined previously knownPlayers.append(pID) pTyp = t.PlayerControls(pInfo.type) rReq = t.SelectRaces(pInfo.race_requested) if pID == thisPlayer.playerID: continue # already updated for p in config.players: # ensure joined player is identified appropriately if p.playerID: continue # ignore players with an already-set playerID if p.type == pTyp and p.selectedRace == rReq: # matched player config.updateID(pID, p) print("[HOSTGAME] %s joined the match." % (p)) pID = 0 # declare that the player has been identified break if pID: raise c.UknownPlayer("could not match %s %s %s to any " "existing player of %s" % (pID, pTyp, rReq, config.players)) if debug: print("all %d player(s) found; game has " # status: init_game "started! (%s)" % (numExpectedPlayers, controller.status)) config.save() # "publish" the configuration file for other procs try: agentCallBack( config.name ) # send the configuration to the controlling agent's pipeline except Exception as e: print("ERROR: agent %s crashed during init: %s (%s)" % (thisPlayer.initCmd, e, type(e))) return (rh.playerCrashed(config), "" ) # no replay information to get startWaitTime = now() while True: # wait for game to end while players/bots do their thing obs = getGameState() result = obs.player_result if result: # match end condition was supplied by the host finalResult = rh.idPlayerResults(config, result) break try: agentCallBack(obs) # do developer's creative stuff except Exception as e: print( "%s ERROR: agent callback %s of %s crashed during game: %s" % (type(e), agentCallBack, thisPlayer.initCmd, e)) finalResult = rh.playerCrashed(config) break newNow = now( ) # periodicially acquire the game's replay data (in case of abnormal termination) if newNow - startWaitTime > c.REPLAY_SAVE_FREQUENCY: replayData = controller.save_replay() startWaitTime = newNow replayData = controller.save_replay( ) # one final attempt to get the complete replay data #controller.leave() # the connection to the server process is (cleanly) severed except (protocol.ConnectionError, protocol.ProtocolError, remote_controller.RequestError) as e: if "Status.in_game" in str( e ): # state was previously in game and then exited that state finalResult = rh.playerSurrendered( config) # rage quit is losing else: finalResult = rh.playerDisconnected(config) print( "%s Connection to game host has ended, even intentionally by agent. Message:%s%s" % (type(e), os.linesep, e)) except KeyboardInterrupt: if debug: print( "caught command to forcibly shutdown Starcraft2 host process." ) finalResult = rh.playerSurrendered(config) finally: if replayData: # ensure replay data can be transmitted over http replayData = base64.encodestring( replayData).decode() # convert raw bytes into str controller.quit() # force the sc2 application to close return (finalResult, replayData)
def main(unused_argv): interface = sc_pb.InterfaceOptions() interface.raw = True interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 84 interface.feature_layer.resolution.y = 84 interface.feature_layer.minimap_resolution.x = 64 interface.feature_layer.minimap_resolution.y = 64 timeline = [] start = time.time() run_config = run_configs.get() proc = run_config.start() process = psutil.Process(proc.pid) def add(s): cpu = process.cpu_times().user mem = process.memory_info().rss / 2 ** 20 # In Mb timeline.append((time.time() - start, cpu, mem, s)) if mem > 2000: raise Exception("2gb mem limit exceeded") try: add("Started") controller = proc.controller map_inst = maps.get("Simple64") create = sc_pb.RequestCreateGame( realtime=False, disable_fog=False, local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.CheatInsane) join = sc_pb.RequestJoinGame(race=sc_common.Random, options=interface) controller.create_game(create) add("Created") controller.join_game(join) add("Joined") for _ in range(30): for i in range(2000): controller.step(16) obs = controller.observe() if obs.player_result: add("Lost") break if i % 100 == 0: add(i) controller.restart() add("Restarted") add("Done") except KeyboardInterrupt: pass finally: proc.close() print("Timeline:") for t in timeline: print("[%7.3f] cpu: %5.1f s, mem: %4d M; %s" % t)
def test_observe_players(self): players = 2 # Can be 1. run_config = run_configs.get() parallel = run_parallel.RunParallel() map_inst = maps.get("Simple64") screen_size_px = point.Point(64, 64) minimap_size_px = point.Point(32, 32) interface = sc_pb.InterfaceOptions(raw=True, score=True) screen_size_px.assign_to(interface.feature_layer.resolution) minimap_size_px.assign_to(interface.feature_layer.minimap_resolution) # Reserve a whole bunch of ports for the weird multiplayer implementation. ports = portspicker.pick_unused_ports((players + 2) * 2) logging.info("Valid Ports: %s", ports) # Actually launch the game processes. print_stage("start") sc2_procs = [run_config.start(extra_ports=ports, want_rgb=False) for _ in range(players + 1)] controllers = [p.controller for p in sc2_procs] try: # Save the maps so they can access it. map_path = os.path.basename(map_inst.path) print_stage("save_map") parallel.run((c.save_map, map_path, map_inst.data(run_config)) for c in controllers) # Create the create request. create = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=map_path)) create.player_setup.add(type=sc_pb.Participant) if players == 1: create.player_setup.add(type=sc_pb.Computer, race=sc_common.Random, difficulty=sc_pb.VeryEasy) else: create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Observer) # Create the join request. joins = [] portIdx = 2 for i in range(players + 1): join = sc_pb.RequestJoinGame(options=interface) if i < players: join.race = sc_common.Random else: join.observed_player_id = 0 join.host_ip = sc2_procs[0].host join.shared_port = 0 # unused join.server_ports.game_port = ports[0] join.server_ports.base_port = ports[1] join.client_ports.add(game_port=ports[portIdx], base_port=ports[portIdx + 1]) portIdx = portIdx + 2 joins.append(join) # Create and Join print_stage("create") controllers[0].create_game(create) print_stage("join") parallel.run((c.join_game, join) for c, join in zip(controllers, joins)) print_stage("run") for game_loop in range(1, 10): # steps per episode # Step the game parallel.run((c.step, 16) for c in controllers) # Observe obs = parallel.run(c.observe for c in controllers) for p_id, o in enumerate(obs): self.assertEqual(o.observation.game_loop, game_loop * 16) if p_id == players: # ie the observer self.assertEqual(o.observation.player_common.player_id, 0) else: self.assertEqual(o.observation.player_common.player_id, p_id + 1) # Act actions = [sc_pb.Action() for _ in range(players)] for action in actions: pt = (point.Point.unit_rand() * minimap_size_px).floor() pt.assign_to(action.action_feature_layer.camera_move.center_minimap) parallel.run((c.act, a) for c, a in zip(controllers[:players], actions)) # Done this game. print_stage("leave") parallel.run(c.leave for c in controllers) finally: print_stage("quit") # Done, shut down. Don't depend on parallel since it might be broken. for c in controllers: c.quit() for p in sc2_procs: p.close() portspicker.return_ports(ports)
def main(unused_argv): """Run SC2 to play a game or a replay.""" if FLAGS.trace: stopwatch.sw.trace() elif FLAGS.profile: stopwatch.sw.enable() if (FLAGS.map and FLAGS.replay) or (not FLAGS.map and not FLAGS.replay): sys.exit("Must supply either a map or replay.") if FLAGS.replay and not FLAGS.replay.lower().endswith("sc2replay"): sys.exit("Replay must end in .SC2Replay.") if FLAGS.realtime and FLAGS.replay: # TODO(tewalds): Support realtime in replays once the game supports it. sys.exit("realtime isn't possible for replays yet.") if FLAGS.render and (FLAGS.realtime or FLAGS.full_screen): sys.exit("disable pygame rendering if you want realtime or full_screen.") if platform.system() == "Linux" and (FLAGS.realtime or FLAGS.full_screen): sys.exit("realtime and full_screen only make sense on Windows/MacOS.") if not FLAGS.render and FLAGS.render_sync: sys.exit("render_sync only makes sense with pygame rendering on.") run_config = run_configs.get() interface = sc_pb.InterfaceOptions() interface.raw = FLAGS.render interface.raw_affects_selection = True interface.raw_crop_to_playable_area = True interface.score = True interface.show_cloaked = True interface.show_burrowed_shadows = True interface.show_placeholders = True if FLAGS.feature_screen_size and FLAGS.feature_minimap_size: interface.feature_layer.width = FLAGS.feature_camera_width FLAGS.feature_screen_size.assign_to(interface.feature_layer.resolution) FLAGS.feature_minimap_size.assign_to( interface.feature_layer.minimap_resolution) interface.feature_layer.crop_to_playable_area = True interface.feature_layer.allow_cheating_layers = True if FLAGS.render and FLAGS.rgb_screen_size and FLAGS.rgb_minimap_size: FLAGS.rgb_screen_size.assign_to(interface.render.resolution) FLAGS.rgb_minimap_size.assign_to(interface.render.minimap_resolution) max_episode_steps = FLAGS.max_episode_steps if FLAGS.map: create = sc_pb.RequestCreateGame( realtime=FLAGS.realtime, disable_fog=FLAGS.disable_fog) try: map_inst = maps.get(FLAGS.map) except maps.lib.NoMapError: if FLAGS.battle_net_map: create.battlenet_map_name = FLAGS.map else: raise else: if map_inst.game_steps_per_episode: max_episode_steps = map_inst.game_steps_per_episode if FLAGS.battle_net_map: create.battlenet_map_name = map_inst.battle_net else: create.local_map.map_path = map_inst.path create.local_map.map_data = map_inst.data(run_config) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc2_env.Race[FLAGS.bot_race], difficulty=sc2_env.Difficulty[FLAGS.difficulty], ai_build=sc2_env.BotBuild[FLAGS.bot_build]) join = sc_pb.RequestJoinGame( options=interface, race=sc2_env.Race[FLAGS.user_race], player_name=FLAGS.user_name) version = None else: replay_data = run_config.replay_data(FLAGS.replay) start_replay = sc_pb.RequestStartReplay( replay_data=replay_data, options=interface, disable_fog=FLAGS.disable_fog, observed_player_id=FLAGS.observed_player) version = replay.get_replay_version(replay_data) run_config = run_configs.get(version=version) # Replace the run config. with run_config.start( full_screen=FLAGS.full_screen, window_size=FLAGS.window_size, want_rgb=interface.HasField("render")) as controller: if FLAGS.map: controller.create_game(create) controller.join_game(join) else: info = controller.replay_info(replay_data) print(" Replay info ".center(60, "-")) print(info) print("-" * 60) map_path = FLAGS.map_path or info.local_map_path if map_path: start_replay.map_data = run_config.map_data(map_path, len(info.player_info)) controller.start_replay(start_replay) if FLAGS.render: renderer = renderer_human.RendererHuman( fps=FLAGS.fps, step_mul=FLAGS.step_mul, render_sync=FLAGS.render_sync, video=FLAGS.video) renderer.run( run_config, controller, max_game_steps=FLAGS.max_game_steps, game_steps_per_episode=max_episode_steps, save_replay=FLAGS.save_replay) else: # Still step forward so the Mac/Windows renderer works. try: while True: frame_start_time = time.time() if not FLAGS.realtime: controller.step(FLAGS.step_mul) obs = controller.observe() if obs.player_result: break time.sleep(max(0, frame_start_time + 1 / FLAGS.fps - time.time())) except KeyboardInterrupt: pass print("Score: ", obs.observation.score.score) print("Result: ", obs.player_result) if FLAGS.map and FLAGS.save_replay: replay_save_loc = run_config.save_replay( controller.save_replay(), "local", FLAGS.map) print("Replay saved to:", replay_save_loc) # Save scores so we know how the human player did. with open(replay_save_loc.replace("SC2Replay", "txt"), "w") as f: f.write("{}\n".format(obs.observation.score.score)) if FLAGS.profile: print(stopwatch.sw)
def main(unused_argv): """Run SC2 to play a game or a replay.""" stopwatch.sw.enabled = FLAGS.profile or FLAGS.trace stopwatch.sw.trace = FLAGS.trace if (FLAGS.map and FLAGS.replay) or (not FLAGS.map and not FLAGS.replay): sys.exit("Must supply either a map or replay.") if FLAGS.replay and not FLAGS.replay.lower().endswith("sc2replay"): sys.exit("Replay must end in .SC2Replay.") if FLAGS.realtime and FLAGS.replay: # TODO(tewalds): Support realtime in replays once the game supports it. sys.exit("realtime isn't possible for replays yet.") if FLAGS.render and (FLAGS.realtime or FLAGS.full_screen): sys.exit("disable pygame rendering if you want realtime or full_screen.") if platform.system() == "Linux" and (FLAGS.realtime or FLAGS.full_screen): sys.exit("realtime and full_screen only make sense on Windows/MacOS.") if not FLAGS.render and FLAGS.render_sync: sys.exit("render_sync only makes sense with pygame rendering on.") run_config = run_configs.get() interface = sc_pb.InterfaceOptions() interface.raw = FLAGS.render interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = FLAGS.screen_resolution interface.feature_layer.resolution.y = FLAGS.screen_resolution interface.feature_layer.minimap_resolution.x = FLAGS.minimap_resolution interface.feature_layer.minimap_resolution.y = FLAGS.minimap_resolution max_episode_steps = FLAGS.max_episode_steps if FLAGS.map: map_inst = maps.get(FLAGS.map) if map_inst.game_steps_per_episode: max_episode_steps = map_inst.game_steps_per_episode create = sc_pb.RequestCreateGame( realtime=FLAGS.realtime, disable_fog=FLAGS.disable_fog, local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc2_env.races[FLAGS.bot_race], difficulty=sc2_env.difficulties[FLAGS.difficulty]) join = sc_pb.RequestJoinGame(race=sc2_env.races[FLAGS.user_race], options=interface) game_version = None else: replay_data = run_config.replay_data(FLAGS.replay) start_replay = sc_pb.RequestStartReplay( replay_data=replay_data, options=interface, disable_fog=FLAGS.disable_fog, observed_player_id=FLAGS.observed_player) game_version = get_game_version(replay_data) with run_config.start(game_version=game_version, full_screen=FLAGS.full_screen) as controller: if FLAGS.map: controller.create_game(create) controller.join_game(join) else: info = controller.replay_info(replay_data) print(" Replay info ".center(60, "-")) print(info) print("-" * 60) map_path = FLAGS.map_path or info.local_map_path if map_path: start_replay.map_data = run_config.map_data(map_path) controller.start_replay(start_replay) if FLAGS.render: renderer = renderer_human.RendererHuman( fps=FLAGS.fps, step_mul=FLAGS.step_mul, render_sync=FLAGS.render_sync) renderer.run( run_config, controller, max_game_steps=FLAGS.max_game_steps, game_steps_per_episode=max_episode_steps, save_replay=FLAGS.save_replay) else: # Still step forward so the Mac/Windows renderer works. try: while True: frame_start_time = time.time() if not FLAGS.realtime: controller.step(FLAGS.step_mul) obs = controller.observe() if obs.player_result: break time.sleep(max(0, frame_start_time + 1 / FLAGS.fps - time.time())) except KeyboardInterrupt: pass print("Score: ", obs.observation.score.score) print("Result: ", obs.player_result) if FLAGS.map and FLAGS.save_replay: replay_save_loc = run_config.save_replay( controller.save_replay(), "local", FLAGS.map) print("Replay saved to:", replay_save_loc) # Save scores so we know how the human player did. with open(replay_save_loc.replace("SC2Replay", "txt"), "w") as f: f.write("{}\n".format(obs.observation.score.score)) if FLAGS.profile: print(stopwatch.sw)
"""Initialize""" # Try to make a connection with SC2 test_client = Core() test_client.init() """Create Game""" #Make Request(CreateGame) #COMMNET TO TEST map_info = sc_pb.LocalMap() #Windows #map_info.map_path = "C:\Program Files (x86)\StarCraft II\Maps\Melee\Simple128.SC2Map" #Mac map_info.map_path = "/Applications/StarCraft II/Maps/Melee/Simple128.SC2Map" create_game = sc_pb.RequestCreateGame(local_map = map_info) create_game.player_setup.add(type=1) create_game.player_setup.add(type=2) create_game.realtime = True print("Make") #send Request print(test_client.comm.send(create_game = create_game)) #print (test_client.comm.read()) """Join Game""" #Make Requst(JoinGame) interface_options = sc_pb.InterfaceOptions(raw = True, score = False) join_game = sc_pb.RequestJoinGame(race = 3, options = interface_options) #send Request
def test_render(self, version): interface = sc_pb.InterfaceOptions() interface.raw = True interface.score = True interface.feature_layer.width = 24 interface.feature_layer.resolution.x = 256 interface.feature_layer.resolution.y = 256 interface.feature_layer.minimap_resolution.x = 152 interface.feature_layer.minimap_resolution.y = 168 interface.render.resolution.x = 256 interface.render.resolution.y = 256 interface.render.minimap_resolution.x = 128 interface.render.minimap_resolution.y = 128 # Delete this line in Mac # os.environ['SC2PATH'] = os.path.join('/root/', version) run_config = run_configs.get() with run_config.start(version=version) as controller: map_inst = maps.get("KairosJunction") create = sc_pb.RequestCreateGame( realtime=False, disable_fog=False, local_map=sc_pb.LocalMap(map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant, race=sc_common.Zerg) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Zerg, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame(race=sc_common.Zerg, options=interface) controller.create_game(create) controller.join_game(join) controller.step(100) game_info = controller.game_info() observation = controller.observe() placement_grid = norm_img( bitmap2array(game_info.start_raw.placement_grid)) pathing_grid = norm_img( bitmap2array(game_info.start_raw.pathing_grid)) creep = norm_img( bitmap2array(observation.observation.raw_data.map_state.creep)) # 0=Hidden, 1=Fogged, 2=Visible, 3=FullHidden visibility = bitmap2array( observation.observation.raw_data.map_state.visibility) visibility = np.equal(visibility, 2) creep_minimap = bitmap2array( observation.observation.feature_layer_data.minimap_renders. creep) creep_minimap = norm_img(np.array(creep_minimap, np.int32)) height_map = bitmap2array( observation.observation.feature_layer_data.minimap_renders. height_map) height_map = norm_img(np.array(height_map, np.int32)) visibility_minimap = bitmap2array( observation.observation.feature_layer_data.minimap_renders. visibility_map) visibility_minimap = np.equal(visibility_minimap, 2) imwrite('images/' + version + '_creep.jpg', creep.astype(np.float32)) imwrite('images/' + version + '_placement_grid.jpg', placement_grid.astype(np.float32)) imwrite('images/' + version + '_pathing_grid.jpg', pathing_grid.astype(np.float32)) imwrite('images/' + version + '_visibility.jpg', visibility.astype(np.float32)) imwrite('images/' + version + '_creep_minimap.jpg', creep_minimap.astype(np.float32)) imwrite('images/' + version + '_height_map.jpg', height_map.astype(np.float32)) imwrite('images/' + version + '_visibility_minimap.jpg', visibility_minimap.astype(np.float32))
def test_multi_player(self): run_config = run_configs.get() map_inst = maps.get("Simple64") with run_config.start(want_rgb=False) as controller: create = sc_pb.RequestCreateGame(local_map=sc_pb.LocalMap( map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Terran, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame( race=sc_common.Terran, options=sc_pb.InterfaceOptions(raw=True)) controller.create_game(create) controller.join_game(join) info = controller.game_info() map_size = info.start_raw.map_size controller.step(2) obs = controller.observe() def get_marines(obs): return { u.tag: u for u in obs.observation.raw_data.units if u.unit_type == units.Terran.Marine } self.assertEmpty(get_marines(obs)) controller.debug( sc_debug.DebugCommand(create_unit=sc_debug.DebugCreateUnit( unit_type=units.Terran.Marine, owner=1, pos=sc_common.Point2D(x=map_size.x // 2, y=map_size.y // 2), quantity=5))) controller.step(2) obs = controller.observe() marines = get_marines(obs) self.assertEqual(5, len(marines)) tags = sorted(marines.keys()) controller.debug([ sc_debug.DebugCommand(kill_unit=sc_debug.DebugKillUnit( tag=[tags[0]])), sc_debug.DebugCommand(unit_value=sc_debug.DebugSetUnitValue( unit_value=sc_debug.DebugSetUnitValue.Life, value=5, unit_tag=tags[1])), ]) controller.step(2) obs = controller.observe() marines = get_marines(obs) self.assertEqual(4, len(marines)) self.assertNotIn(tags[0], marines) self.assertEqual(marines[tags[1]].health, 5)
def test_multi_player(self): players = 2 run_config = run_configs.get() parallel = run_parallel.RunParallel() map_inst = maps.get("Simple64") screen_size_px = point.Point(64, 64) minimap_size_px = point.Point(32, 32) interface = sc_pb.InterfaceOptions() screen_size_px.assign_to(interface.feature_layer.resolution) minimap_size_px.assign_to(interface.feature_layer.minimap_resolution) # Reserve a whole bunch of ports for the weird multiplayer implementation. ports = portspicker.pick_unused_ports(players * 2) logging.info("Valid Ports: %s", ports) # Actually launch the game processes. print_stage("start") sc2_procs = [run_config.start(extra_ports=ports) for _ in range(players)] controllers = [p.controller for p in sc2_procs] try: # Save the maps so they can access it. map_path = os.path.basename(map_inst.path) print_stage("save_map") parallel.run((c.save_map, map_path, map_inst.data(run_config)) for c in controllers) # Create the create request. create = sc_pb.RequestCreateGame( local_map=sc_pb.LocalMap(map_path=map_path)) for _ in range(players): create.player_setup.add(type=sc_pb.Participant) # Create the join request. join = sc_pb.RequestJoinGame(race=sc_common.Random, options=interface) join.shared_port = 0 # unused join.server_ports.game_port = ports.pop(0) join.server_ports.base_port = ports.pop(0) for _ in range(players - 1): join.client_ports.add(game_port=ports.pop(0), base_port=ports.pop(0)) # Play a few short games. for _ in range(2): # 2 episodes # Create and Join print_stage("create") controllers[0].create_game(create) print_stage("join") parallel.run((c.join_game, join) for c in controllers) print_stage("run") for game_loop in range(1, 10): # steps per episode # Step the game parallel.run(c.step for c in controllers) # Observe obs = parallel.run(c.observe for c in controllers) for p_id, o in enumerate(obs): self.assertEqual(o.observation.game_loop, game_loop) self.assertEqual(o.observation.player_common.player_id, p_id + 1) # Act actions = [sc_pb.Action() for _ in range(players)] for action in actions: pt = (point.Point.unit_rand() * minimap_size_px).floor() pt.assign_to(action.action_feature_layer.camera_move.center_minimap) parallel.run((c.act, a) for c, a in zip(controllers, actions)) # Done this game. print_stage("leave") parallel.run(c.leave for c in controllers) finally: print_stage("quit") # Done, shut down. Don't depend on parallel since it might be broken. for c in controllers: c.quit() for p in sc2_procs: p.close() portspicker.return_ports(ports)
def human(): """Run a host which expects one player to connect remotely.""" run_config = run_configs.get() map_inst = maps.get(FLAGS.map) if not FLAGS.rgb_screen_size or not FLAGS.rgb_minimap_size: logging.info( "Use --rgb_screen_size and --rgb_minimap_size if you want rgb " "observations.") ports = [FLAGS.config_port + p for p in range(5)] # tcp + 2 * num_players if not all(portpicker.is_port_free(p) for p in ports): sys.exit("Need 5 free ports after the config port.") proc = None ssh_proc = None tcp_conn = None udp_sock = None try: proc = run_config.start(extra_ports=ports[1:], timeout_seconds=300, host=FLAGS.host, window_loc=(50, 50)) tcp_port = ports[0] settings = { "remote": FLAGS.remote, "game_version": proc.version.game_version, "realtime": FLAGS.realtime, "map_name": map_inst.name, "map_path": map_inst.path, "map_data": map_inst.data(run_config), "ports": { "server": { "game": ports[1], "base": ports[2] }, "client": { "game": ports[3], "base": ports[4] }, } } create = sc_pb.RequestCreateGame( realtime=settings["realtime"], local_map=sc_pb.LocalMap(map_path=settings["map_path"])) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Participant) controller = proc.controller controller.save_map(settings["map_path"], settings["map_data"]) controller.create_game(create) if FLAGS.remote: ssh_proc = lan_sc2_env.forward_ports( FLAGS.remote, proc.host, [settings["ports"]["client"]["base"]], [tcp_port, settings["ports"]["server"]["base"]]) print("-" * 80) print("Join: play_vs_agent --host %s --config_port %s" % (proc.host, tcp_port)) print("-" * 80) tcp_conn = lan_sc2_env.tcp_server( lan_sc2_env.Addr(proc.host, tcp_port), settings) if FLAGS.remote: udp_sock = lan_sc2_env.udp_server( lan_sc2_env.Addr(proc.host, settings["ports"]["client"]["game"])) lan_sc2_env.daemon_thread( lan_sc2_env.tcp_to_udp, (tcp_conn, udp_sock, lan_sc2_env.Addr(proc.host, settings["ports"]["server"]["game"]))) lan_sc2_env.daemon_thread(lan_sc2_env.udp_to_tcp, (udp_sock, tcp_conn)) join = sc_pb.RequestJoinGame() join.shared_port = 0 # unused join.server_ports.game_port = settings["ports"]["server"]["game"] join.server_ports.base_port = settings["ports"]["server"]["base"] join.client_ports.add(game_port=settings["ports"]["client"]["game"], base_port=settings["ports"]["client"]["base"]) join.race = sc2_env.Race[FLAGS.user_race] join.player_name = FLAGS.user_name if FLAGS.render: join.options.raw = True join.options.score = True if FLAGS.feature_screen_size and FLAGS.feature_minimap_size: fl = join.options.feature_layer fl.width = 24 FLAGS.feature_screen_size.assign_to(fl.resolution) FLAGS.feature_minimap_size.assign_to(fl.minimap_resolution) if FLAGS.rgb_screen_size and FLAGS.rgb_minimap_size: FLAGS.rgb_screen_size.assign_to(join.options.render.resolution) FLAGS.rgb_minimap_size.assign_to( join.options.render.minimap_resolution) controller.join_game(join) if FLAGS.render: renderer = renderer_human.RendererHuman(fps=FLAGS.fps, render_feature_grid=False) renderer.run(run_configs.get(), controller, max_episodes=1) else: # Still step forward so the Mac/Windows renderer works. while True: frame_start_time = time.time() if not FLAGS.realtime: controller.step() obs = controller.observe() if obs.player_result: break time.sleep( max(0, frame_start_time - time.time() + 1 / FLAGS.fps)) except KeyboardInterrupt: pass finally: if tcp_conn: tcp_conn.close() if proc: proc.close() if udp_sock: udp_sock.close() if ssh_proc: ssh_proc.terminate() for _ in range(5): if ssh_proc.poll() is not None: break time.sleep(1) if ssh_proc.poll() is None: ssh_proc.kill() ssh_proc.wait()
def run(debug=False): """PURPOSE: start a starcraft2 process using the defined the config parameters""" FLAGS(sys.argv) config = gameConfig.Config( version= None, # vers is None... unless a specific game version is desired themap=selectMap(ladder=True), # pick a random ladder map players=["defaulthuman", "blizzbot2_easy"], ) createReq = sc_pb.RequestCreateGame( # used to advance to "Init Game" state, when hosting realtime=config.realtime, disable_fog=config.fogDisabled, random_seed=int(now( )), # a game is created using the current second timestamp as the seed local_map=sc_pb.LocalMap(map_path=config.mapLocalPath, map_data=config.mapData)) joinRace = None for player in config.players: reqPlayer = createReq.player_setup.add( ) # add new player; get link to settings playerObj = PlayerPreGame(player) if playerObj.isComputer: reqPlayer.difficulty = playerObj.difficulty.gameValue() pType = playerObj.type.type else: pType = c.PARTICIPANT reqPlayer.type = t.PlayerControls(pType).gameValue() reqPlayer.race = playerObj.selectedRace.gameValue() if not playerObj.isComputer: joinRace = reqPlayer.race interface = sc_pb.InterfaceOptions() raw, score, feature, rendered = config.interfaces interface.raw = raw # whether raw data is reported in observations interface.score = score # whether score data is reported in observations interface.feature_layer.width = 24 joinReq = sc_pb.RequestJoinGame( options=interface) # SC2APIProtocol.RequestJoinGame joinReq.race = joinRace # update joinGame request as necessary if debug: print("Starcraft2 game process is launching.") controller = None with config.launchApp() as controller: try: if debug: print("Starcraft2 application is live. (%s)" % (controller.status)) # status: launched controller.create_game(createReq) if debug: print( "Starcraft2 is waiting for %d player(s) to join. (%s)" % (config.numAgents, controller.status)) # status: init_game playerID = controller.join_game( joinReq).player_id # SC2APIProtocol.RequestJoinGame print("[GET IN-GAME DATA] player#%d %s" % (playerID, config)) return (controller.ping(), controller.data()) except (protocol.ConnectionError, protocol.ProtocolError, remote_controller.RequestError) as e: if debug: print("%s Connection to game closed (NOT a bug)%s%s" % (type(e), os.linesep, e)) else: print("Connection to game closed.") except KeyboardInterrupt: print( "caught command to forcibly shutdown Starcraft2 host server.") finally: config.disable( ) # if the saved cfg file still exists, always remove it controller.quit() # force the sc2 application to close
def main(unused_argv): stopwatch.sw.enable() results = [] try: for config, interface in configs: print((" Starting: %s " % config).center(60, "-")) timeline = [] run_config = run_configs.get() if FLAGS.replay: replay_data = run_config.replay_data(FLAGS.replay) start_replay = sc_pb.RequestStartReplay( replay_data=replay_data, options=interface, disable_fog=False, observed_player_id=2) version = replay.get_replay_version(replay_data) run_config = run_configs.get( version=version) # Replace the run config. else: map_inst = maps.get(FLAGS.map) create = sc_pb.RequestCreateGame( realtime=False, disable_fog=False, random_seed=1, local_map=sc_pb.LocalMap( map_path=map_inst.path, map_data=map_inst.data(run_config))) create.player_setup.add(type=sc_pb.Participant) create.player_setup.add(type=sc_pb.Computer, race=sc_common.Terran, difficulty=sc_pb.VeryEasy) join = sc_pb.RequestJoinGame(options=interface, race=sc_common.Protoss) with run_config.start( want_rgb=interface.HasField("render")) as controller: if FLAGS.replay: info = controller.replay_info(replay_data) print(" Replay info ".center(60, "-")) print(info) print("-" * 60) if info.local_map_path: start_replay.map_data = run_config.map_data( info.local_map_path) controller.start_replay(start_replay) else: controller.create_game(create) controller.join_game(join) for _ in range(FLAGS.count): controller.step(FLAGS.step_mul) start = time.time() obs = controller.observe() timeline.append(time.time() - start) if obs.player_result: break results.append((config, timeline)) except KeyboardInterrupt: pass names, values = zip(*results) print("\n\nTimeline:\n") print(",".join(names)) for times in zip(*values): print(",".join("%0.2f" % (t * 1000) for t in times)) print(stopwatch.sw)