def testFilteredIn(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( feature_layer_data=spatial_pb2.ObservationFeatureLayer( renders=spatial_pb2.FeatureLayers( height_map=common_pb2.ImageData( bits_per_pixel=32, size=common_pb2.Size2DI(x=4, y=4), data=np.array([[0, 0, 0, 0], [1, 0, 1, 0], [0, 0, 0, 1], [1, 1, 1, 1]], dtype=np.int32).tobytes()))))) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( feature_layer_data=spatial_pb2.ObservationFeatureLayer( renders=spatial_pb2.FeatureLayers( height_map=common_pb2.ImageData( bits_per_pixel=32, size=common_pb2.Size2DI(x=4, y=4), data=np.array([[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 0, 1], [1, 1, 1, 0]], dtype=np.int32).tobytes()))))) result = image_differencer.image_differencer(path=proto_diff.ProtoPath( ("observation", "feature_layer_data", "renders", "height_map", "data")), proto_a=a, proto_b=b) self.assertEqual( result, "3 element(s) changed - [1][0]: 1 -> 0; [1][1]: 0 -> 1; [3][3]: 1 -> 0" )
def testRemovedField(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1)) b = sc_pb.ResponseObservation(observation=sc_pb.Observation()) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.removed, 1, diff) self.assertEqual(str(diff.removed[0]), "observation.game_loop") self.assertEqual(diff.removed, diff.all_diffs()) self.assertEqual(diff.report(), "Removed observation.game_loop.")
def testTruncation(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, alerts=[sc_pb.AlertError, sc_pb.LarvaHatched])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=2, alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertEqual( diff.report([_alert_formatter], truncate_to=9), "Changed observation.alerts[1]: LarvaH....\n" "Changed observation.game_loop: 1 -> 2.") self.assertEqual( diff.report([_alert_formatter], truncate_to=-1), "Changed observation.alerts[1]: ....\n" "Changed observation.game_loop: ... -> ....")
def testAddedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError, sc_pb.MergeComplete]), player_result=[sc_pb.PlayerResult()]) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.added, 2, diff) self.assertEqual(str(diff.added[0]), "observation.alerts[1]") self.assertEqual(str(diff.added[1]), "player_result") self.assertEqual(diff.added, diff.all_diffs()) self.assertEqual( diff.report(), "Added observation.alerts[1].\n" "Added player_result.")
def init(self, game_info, static_data): """Take the game info and the static data needed to set up the game. This must be called before render or get_actions for each game or restart. Args: game_info: A `sc_pb.ResponseGameInfo` object for this game. static_data: A `StaticData` object for this game. """ self._game_info = game_info self._static_data = static_data self._map_size = point.Point.build(game_info.start_raw.map_size) fl_opts = game_info.options.feature_layer self._feature_layer_screen_size = point.Point.build(fl_opts.resolution) self._feature_layer_minimap_size = point.Point.build( fl_opts.minimap_resolution) self._camera_width_world_units = fl_opts.width try: self.init_window() self._initialized = True except pygame.error as e: self._initialized = False logging.error("-" * 60) logging.error("Failed to initialize pygame: %s", e) logging.error("Continuing without pygame.") logging.error("If you're using ssh and have an X server, try ssh -X.") logging.error("-" * 60) self._obs = sc_pb.ResponseObservation() self.queued_action = None self.queued_hotkey = "" self.select_start = None self.help = False
def build(self): """Builds and returns a proto ResponseObservation.""" response_observation = sc_pb.ResponseObservation() obs = response_observation.observation obs.game_loop = self._game_loop obs.player_common.CopyFrom(self._player_common) obs.abilities.add(ability_id=1, requires_point=True) # Smart obs.score.score = self._score obs.score.score_details.CopyFrom(self._score_details) def fill(image_data, size, bits): image_data.bits_per_pixel = bits image_data.size.y = size[0] image_data.size.x = size[1] image_data.data = b'\0' * int(math.ceil(size[0] * size[1] * bits / 8)) if 'feature_screen' in self._obs_spec: for feature in features.SCREEN_FEATURES: fill(getattr(obs.feature_layer_data.renders, feature.name), self._obs_spec['feature_screen'][1:], 8) if 'feature_minimap' in self._obs_spec: for feature in features.MINIMAP_FEATURES: fill(getattr(obs.feature_layer_data.minimap_renders, feature.name), self._obs_spec['feature_minimap'][1:], 8) if 'rgb_screen' in self._obs_spec: fill(obs.render_data.map, self._obs_spec['rgb_screen'][:2], 24) if 'rgb_minimap' in self._obs_spec: fill(obs.render_data.minimap, self._obs_spec['rgb_minimap'][:2], 24) if self._single_select: self._single_select.fill(obs.ui_data.single.unit) if self._multi_select: for unit in self._multi_select: obs.ui_data.multi.units.add(**unit.as_dict()) if self._build_queue: for unit in self._build_queue: obs.ui_data.production.build_queue.add(**unit.as_dict()) if self._production: for item in self._production: obs.ui_data.production.production_queue.add(**item) if self._feature_units: for tag, feature_unit in enumerate(self._feature_units, 1): args = dict(tag=tag) args.update(feature_unit.as_dict()) obs.raw_data.units.add(**args) return response_observation
def testRemovedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, score=score_pb2.Score(), alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( alerts=[sc_pb.AlertError])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.removed, 3, diff) self.assertEqual(str(diff.removed[0]), "observation.alerts[1]") self.assertEqual(str(diff.removed[1]), "observation.game_loop") self.assertEqual(str(diff.removed[2]), "observation.score") self.assertEqual(diff.removed, diff.all_diffs()) self.assertEqual( diff.report(), "Removed observation.alerts[1].\n" "Removed observation.game_loop.\n" "Removed observation.score.")
def testChangedFields(self): a = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, alerts=[sc_pb.AlertError, sc_pb.LarvaHatched])) b = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=2, alerts=[sc_pb.AlertError, sc_pb.MergeComplete])) diff = proto_diff.compute_diff(a, b) self.assertIsNotNone(diff) self.assertLen(diff.changed, 2, diff) self.assertEqual(str(diff.changed[0]), "observation.alerts[1]") self.assertEqual(str(diff.changed[1]), "observation.game_loop") self.assertEqual(diff.changed, diff.all_diffs()) self.assertEqual( diff.report(), "Changed observation.alerts[1]: 7 -> 8.\n" "Changed observation.game_loop: 1 -> 2.") self.assertEqual( diff.report([_alert_formatter]), "Changed observation.alerts[1]: LarvaHatched -> MergeComplete.\n" "Changed observation.game_loop: 1 -> 2.")
def init(self, game_info, static_data): """Take the game info and the static data needed to set up the game. This must be called before render or get_actions for each game or restart. Args: game_info: A `sc_pb.ResponseGameInfo` object for this game. static_data: A `StaticData` object for this game. Raises: ValueError: if there is nothing to render. """ self._game_info = game_info self._static_data = static_data if not game_info.HasField("start_raw"): raise ValueError("Raw observations are required for the renderer.") self._map_size = point.Point.build(game_info.start_raw.map_size) if game_info.options.HasField("feature_layer"): fl_opts = game_info.options.feature_layer self._feature_screen_px = point.Point.build(fl_opts.resolution) self._feature_minimap_px = point.Point.build(fl_opts.minimap_resolution) self._feature_camera_width_world_units = fl_opts.width self._render_rgb = False else: self._feature_screen_px = self._feature_minimap_px = None if game_info.options.HasField("render"): render_opts = game_info.options.render self._rgb_screen_px = point.Point.build(render_opts.resolution) self._rgb_minimap_px = point.Point.build(render_opts.minimap_resolution) self._render_rgb = True else: self._rgb_screen_px = self._rgb_minimap_px = None if not self._feature_screen_px and not self._rgb_screen_px: raise ValueError("Nothing to render.") try: self.init_window() self._initialized = True except pygame.error as e: self._initialized = False logging.error("-" * 60) logging.error("Failed to initialize pygame: %s", e) logging.error("Continuing without pygame.") logging.error("If you're using ssh and have an X server, try ssh -X.") logging.error("-" * 60) self._obs = sc_pb.ResponseObservation() self._queued_action = None self._queued_hotkey = "" self._select_start = None self._help = False
def testGetField(self): proto = sc_pb.ResponseObservation(observation=sc_pb.Observation( game_loop=1, alerts=[sc_pb.AlertError])) game_loop = proto_diff.ProtoPath(("observation", "game_loop")) alert = proto_diff.ProtoPath(("observation", "alerts", 0)) self.assertEqual(game_loop.get_field(proto), 1) self.assertEqual(alert.get_field(proto), sc_pb.AlertError) self.assertEqual( proto_diff.ProtoPath(game_loop.path[:-1]).get_field(proto), sc_pb.Observation(game_loop=1, alerts=[sc_pb.AlertError]))
def _default_observation(self): """Returns a mock observation from an SC2Env.""" response_observation = sc_pb.ResponseObservation() obs = response_observation.observation obs.game_loop = 1 obs.player_common.player_id = 1 obs.player_common.minerals = 20 obs.player_common.vespene = 50 obs.player_common.food_cap = 36 obs.player_common.food_used = 21 obs.player_common.food_army = 6 obs.player_common.food_workers = 15 obs.player_common.idle_worker_count = 2 obs.player_common.army_count = 6 obs.player_common.warp_gate_count = 0 obs.player_common.larva_count = 0 obs.abilities.add(ability_id=1, requires_point=True) # Smart obs.score.score = 300 score_details = obs.score.score_details score_details.idle_production_time = 0 score_details.idle_worker_time = 0 score_details.total_value_units = 190 score_details.total_value_structures = 230 score_details.killed_value_units = 0 score_details.killed_value_structures = 0 score_details.collected_minerals = 2130 score_details.collected_vespene = 560 score_details.collection_rate_minerals = 50 score_details.collection_rate_vespene = 20 score_details.spent_minerals = 2000 score_details.spent_vespene = 500 def fill(image_data, size, bits): image_data.bits_per_pixel = bits image_data.size.y = size[0] image_data.size.x = size[1] image_data.data = b'\0' * int( math.ceil(size[0] * size[1] * bits / 8)) obs_spec = self.observation_spec()[0] if 'feature_screen' in obs_spec: for feature in features.SCREEN_FEATURES: fill(getattr(obs.feature_layer_data.renders, feature.name), obs_spec['feature_screen'][1:], 8) if 'feature_minimap' in obs_spec: for feature in features.MINIMAP_FEATURES: fill( getattr(obs.feature_layer_data.minimap_renders, feature.name), obs_spec['feature_minimap'][1:], 8) if 'rgb_screen' in obs_spec: fill(obs.render_data.map, obs_spec['rgb_screen'][:2], 24) if 'rgb_screen' in obs_spec: fill(obs.render_data.minimap, obs_spec['rgb_minimap'][:2], 24) observation = self._features.transform_obs(response_observation) # Add bounding box for the minimap camera in top left of feature screen. if 'feature_minimap' in observation: minimap_camera = observation.feature_minimap.camera minimap_camera.fill(0) height, width = [dim // 2 for dim in minimap_camera.shape] minimap_camera[:height, :width].fill(1) return observation
def build(self): """Builds and returns a proto ResponseObservation.""" response_observation = sc_pb.ResponseObservation() obs = response_observation.observation obs.game_loop = 1 obs.player_common.player_id = 1 obs.player_common.minerals = 20 obs.player_common.vespene = 50 obs.player_common.food_cap = 36 obs.player_common.food_used = 21 obs.player_common.food_army = 6 obs.player_common.food_workers = 15 obs.player_common.idle_worker_count = 2 obs.player_common.army_count = 6 obs.player_common.warp_gate_count = 0 obs.player_common.larva_count = 0 obs.abilities.add(ability_id=1, requires_point=True) # Smart obs.score.score = 300 score_details = obs.score.score_details score_details.idle_production_time = 0 score_details.idle_worker_time = 0 score_details.total_value_units = 190 score_details.total_value_structures = 230 score_details.killed_value_units = 0 score_details.killed_value_structures = 0 score_details.collected_minerals = 2130 score_details.collected_vespene = 560 score_details.collection_rate_minerals = 50 score_details.collection_rate_vespene = 20 score_details.spent_minerals = 2000 score_details.spent_vespene = 500 def fill(image_data, size, bits): image_data.bits_per_pixel = bits image_data.size.y = size[0] image_data.size.x = size[1] image_data.data = b'\0' * int(math.ceil(size[0] * size[1] * bits / 8)) if 'feature_screen' in self._obs_spec: for feature in features.SCREEN_FEATURES: fill(getattr(obs.feature_layer_data.renders, feature.name), self._obs_spec['feature_screen'][1:], 8) if 'feature_minimap' in self._obs_spec: for feature in features.MINIMAP_FEATURES: fill(getattr(obs.feature_layer_data.minimap_renders, feature.name), self._obs_spec['feature_minimap'][1:], 8) if 'rgb_screen' in self._obs_spec: fill(obs.render_data.map, self._obs_spec['rgb_screen'][:2], 24) if 'rgb_minimap' in self._obs_spec: fill(obs.render_data.minimap, self._obs_spec['rgb_minimap'][:2], 24) if self._single_select: self._single_select.fill(obs.ui_data.single.unit) if self._multi_select: for unit in self._multi_select: obs.ui_data.multi.units.add(**unit.as_dict()) if self._build_queue: for unit in self._build_queue: obs.ui_data.production.build_queue.add(**unit.as_dict()) if self._feature_units: for feature_unit in self._feature_units: obs.raw_data.units.add(**feature_unit.as_dict()) return response_observation
def init(self, game_info, static_data): """Take the game info and the static data needed to set up the game. This must be called before render or get_actions for each game or restart. Args: game_info: A `sc_pb.ResponseGameInfo` object for this game. static_data: A `StaticData` object for this game. """ self._game_info = game_info # game info example: ''' map_name: "CombatFocus" local_map_path: "mini_games/DefeatRoaches.SC2Map" player_info { player_id: 1 type: Participant race_requested: Terran race_actual: Terran } player_info { player_id: 2 type: Computer race_requested: Zerg difficulty: Medium } start_raw { map_size { x: 64 y: 64 } pathing_grid { bits_per_pixel: 8 size { x: 64 y: 64 } data: xxxxxxxxx } terrain_height { bits_per_pixel: 8 size { x: 64 y: 64 } data: xxxxxxxxx } placement_grid { bits_per_pixel: 8 size { x: 64 y: 64 } } playable_area { p0 { x: 10 y: 8 } p1 { x: 54 y: 44 } } start_locations { x: 7.5 y: 61.5 } } options { raw: true score: true feature_layer { width: 24.0 resolution { x: 84 y: 84 } minimap_resolution { x: 64 y: 64 } } } mod_names: "Mods/Core.SC2Mod" mod_names: "Mods/Liberty.SC2Mod" mod_names: "Mods/Swarm.SC2Mod" mod_names: "Mods/Void.SC2Mod" mod_names: "Mods/VoidMulti.SC2Mod" ''' print("sc_pb.ResponseGameInfo: ", game_info.player_info) self._static_data = static_data # _map_size (64, 64) self._map_size = point.Point.build(game_info.start_raw.map_size) # fl: feature layer fl_opts = game_info.options.feature_layer # _feature_layer_screen_size (84, 84) self._feature_layer_screen_size = point.Point.build(fl_opts.resolution) # _feature_layer_minimap_size (64, 64) self._feature_layer_minimap_size = point.Point.build( fl_opts.minimap_resolution) # _camera_width_world_units 24 self._camera_width_world_units = fl_opts.width try: self.init_window() self._initialized = True except pygame.error as e: self._initialized = False logging.error("-" * 60) logging.error("Failed to initialize pygame: %s", e) logging.error("Continuing without pygame.") logging.error( "If you're using ssh and have an X server, try ssh -X.") logging.error("-" * 60) self._obs = sc_pb.ResponseObservation() self.queued_action = None self.queued_hotkey = "" self.select_start = None self.help = False
def testNoDiffs(self): a = sc_pb.ResponseObservation() b = sc_pb.ResponseObservation() diff = proto_diff.compute_diff(a, b) self.assertIsNone(diff)
import stream from s2clientprotocol import sc2api_pb2 as sc_pb PATH = 'parsed_replays/SampledActions/Terran_vs_Terran/Terran/7cc6fe85694768dbab7987344196ab44615842bd896f9172ee1177a2b899ba58.SC2Replay' # OBS = [obs for obs in stream.parse(PATH), sc_pb.ResponseObservation)] # print(OBS) for obs in stream.parse(PATH): print(sc_pb.ResponseObservation(obs))