diff --git a/examples/terran/ramp_wall.py b/examples/terran/ramp_wall.py index 2814a1ebf..a8001ea0e 100644 --- a/examples/terran/ramp_wall.py +++ b/examples/terran/ramp_wall.py @@ -1,3 +1,7 @@ +import sys, os + +sys.path.append(os.path.join(os.path.dirname(__file__), "../..")) + import random import sc2 @@ -20,7 +24,6 @@ async def on_step(self, iteration): if self.can_afford(SCV) and self.workers.amount < 16 and cc.is_idle: await self.do(cc.train(SCV)) - # Raise depos when enemies are nearby for depo in self.units(SUPPLYDEPOT).ready: for unit in self.known_enemy_units.not_structure: @@ -47,6 +50,22 @@ async def on_step(self, iteration): depots = self.units(SUPPLYDEPOT) | self.units(SUPPLYDEPOTLOWERED) + # Draw ramp points + # def terrain_to_z_height(h): + # return round(16 * h / 255, 2) + + # for ramp in self.game_info.map_ramps: + # for p in ramp.points: + # h = self.get_terrain_height(p) + # h2 = terrain_to_z_height(h) + # pos = Point3((p.x, p.y, h2)) + # p0 = Point3((pos.x - 0.25, pos.y - 0.25, pos.z)) + # p1 = Point3((pos.x + 0.25, pos.y + 0.25, pos.z - 0.5)) + # print(f"drawing {p0} to {p1}") + # self._client.debug_box_out(p0, p1, color=Point3((255, 0, 0))) + # + # await self._client.send_debug() + # Filter locations close to finished supply depots if depots: depot_placement_positions = {d for d in depot_placement_positions if depots.closest_distance_to(d) > 1} @@ -58,7 +77,7 @@ async def on_step(self, iteration): # Choose any depot location target_depot_location = depot_placement_positions.pop() ws = self.workers.gathering - if ws: # if workers were found + if ws: # if workers were found w = ws.random await self.do(w.build(SUPPLYDEPOT, target_depot_location)) @@ -67,7 +86,7 @@ async def on_step(self, iteration): if self.units(BARRACKS).amount + self.already_pending(BARRACKS) > 0: return ws = self.workers.gathering - if ws and barracks_placement_position: # if workers were found + if ws and barracks_placement_position: # if workers were found w = ws.random await self.do(w.build(BARRACKS, barracks_placement_position)) @@ -87,14 +106,14 @@ def main(): "PortAleksanderLE", "StasisLE", "DarknessSanctuaryLE", - "ParaSiteLE", # Has 5 upper points at the main ramp - "AcolyteLE", # Has 4 upper points at the ramp to the in-base natural and 2 upper points at the small ramp + "ParaSiteLE", # Has 5 upper points at the main ramp + "AcolyteLE", # Has 4 upper points at the ramp to the in-base natural and 2 upper points at the small ramp ] ) - sc2.run_game(sc2.maps.get(map), [ - Bot(Race.Terran, RampWallBot()), - Computer(Race.Zerg, Difficulty.Hard) - ], realtime=False) + sc2.run_game( + sc2.maps.get(map), [Bot(Race.Terran, RampWallBot()), Computer(Race.Zerg, Difficulty.Hard)], realtime=False + ) + -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/sc2/client.py b/sc2/client.py index 105715678..e53ec0ea4 100644 --- a/sc2/client.py +++ b/sc2/client.py @@ -41,7 +41,7 @@ def in_game(self): return self._status == Status.in_game async def join_game(self, name=None, race=None, observed_player_id=None, portconfig=None, rgb_render_config=None): - ifopts = sc_pb.InterfaceOptions(raw=True, score=True, show_cloaked=True, raw_affects_selection=False, raw_crop_to_playable_area=True) + ifopts = sc_pb.InterfaceOptions(raw=True, score=True, show_cloaked=True, raw_affects_selection=False, raw_crop_to_playable_area=False) if rgb_render_config: assert isinstance(rgb_render_config, dict) diff --git a/sc2/game_info.py b/sc2/game_info.py index 2a4c7829f..36df54524 100644 --- a/sc2/game_info.py +++ b/sc2/game_info.py @@ -12,8 +12,8 @@ def __init__(self, points: Set[Point2], game_info: "GameInfo"): self._points: Set[Point2] = points self.__game_info = game_info # tested by printing actual building locations vs calculated depot positions - self.x_offset = 0.5 # might be errors with the pixelmap? - self.y_offset = -0.5 + self.x_offset = 0.5 + self.y_offset = 0.5 self.cache = {} @property_immutable_cache @@ -160,11 +160,11 @@ def __init__(self, proto): self.map_size: Size = Size.from_proto(self._proto.start_raw.map_size) # self.pathing_grid[point]: if 0, point is not pathable, if 1, point is pathable - self.pathing_grid: PixelMap = PixelMap(self._proto.start_raw.pathing_grid, in_bits=True) - # self.terrain_height[point]: returns the height in range of 0 to 255 at that point - self.terrain_height: PixelMap = PixelMap(self._proto.start_raw.terrain_height) - # self.pathing_grid[point]: if 0, point is not pathable, if 1, point is pathable - self.placement_grid: PixelMap = PixelMap(self._proto.start_raw.placement_grid, in_bits=True) + self.pathing_grid: PixelMap = PixelMap(self._proto.start_raw.pathing_grid, in_bits=True, mirrored=False) + # self.terrain_height[point]: returns the height in range of 0 to 255 at that point + self.terrain_height: PixelMap = PixelMap(self._proto.start_raw.terrain_height, mirrored=False) + # self.placement_grid[point]: if 0, point is not pathable, if 1, point is pathable + self.placement_grid: PixelMap = PixelMap(self._proto.start_raw.placement_grid, in_bits=True, mirrored=False) self.playable_area = Rect.from_proto(self._proto.start_raw.playable_area) self.map_center = self.playable_area.center self.map_ramps: List[Ramp] = None # Filled later by BotAI._prepare_first_step @@ -181,7 +181,7 @@ def _find_ramps(self) -> List[Ramp]: Point2((x, y)) for x in range(map_area.x, map_area.x + map_area.width) for y in range(map_area.y, map_area.y + map_area.height) - if self.placement_grid[(x, y)] == 0 and self.pathing_grid[(x, y)] == 0 + if self.placement_grid[(x, y)] == 0 and self.pathing_grid[(x, y)] == 1 ) return [Ramp(group, self) for group in self._find_groups(rampPoints)] diff --git a/sc2/game_state.py b/sc2/game_state.py index ca5e6b357..ecffea36b 100644 --- a/sc2/game_state.py +++ b/sc2/game_state.py @@ -104,6 +104,7 @@ def __repr__(self) -> str: class GameState: def __init__(self, response_observation): + self.response_observation = response_observation self.actions = response_observation.actions # successful actions since last loop self.action_errors = response_observation.action_errors # error actions since last loop @@ -161,10 +162,10 @@ def __init__(self, response_observation): self.blips: Set[Blip] = {Blip(unit) for unit in blipUnits} # self.visibility[point]: 0=Hidden, 1=Fogged, 2=Visible - self.visibility: PixelMap = PixelMap(self.observation_raw.map_state.visibility) - # self.visibility[point]: 0=No creep, 1=creep - self.creep: PixelMap = PixelMap(self.observation_raw.map_state.creep) - + self.visibility: PixelMap = PixelMap(self.observation_raw.map_state.visibility, mirrored=True) + # self.creep[point]: 0=No creep, 1=creep + self.creep: PixelMap = PixelMap(self.observation_raw.map_state.creep, mirrored=True) + # Effects like ravager bile shot, lurker attack, everything in effect_id.py self.effects: Set[EffectData] = {EffectData(effect) for effect in self.observation_raw.effects} """ Usage: diff --git a/sc2/pixel_map.py b/sc2/pixel_map.py index 304230f00..f46e516f1 100644 --- a/sc2/pixel_map.py +++ b/sc2/pixel_map.py @@ -6,7 +6,7 @@ class PixelMap: - def __init__(self, proto, in_bits=False): + def __init__(self, proto, in_bits=False, mirrored=False): self._proto = proto assert self.width * self.height == (8 if in_bits else 1) * len( self._proto.data @@ -14,7 +14,9 @@ def __init__(self, proto, in_bits=False): buffer_data = np.frombuffer(self._proto.data, dtype=np.uint8) if in_bits: buffer_data = np.unpackbits(buffer_data) - self.data_numpy = buffer_data.reshape(self._proto.size.x, self._proto.size.y) + self.data_numpy = buffer_data.reshape(self._proto.size.y, self._proto.size.x) + if mirrored: + self.data_numpy = np.flipud(self.data_numpy) @property def width(self): @@ -33,10 +35,10 @@ def bytes_per_pixel(self): return self._proto.bits_per_pixel // 8 def __getitem__(self, pos): - """ Example usage: is_pathable = self._game_info.pathing_grid[Point2((20, 20))] == 0 """ + """ Example usage: is_pathable = self._game_info.pathing_grid[Point2((20, 20))] != 0 """ assert 0 <= pos[0] < self.width, f"x is {pos[0]}, self.width is {self.width}" assert 0 <= pos[1] < self.height, f"y is {pos[1]}, self.height is {self.height}" - return int(self.data_numpy[pos[0], pos[1]]) + return int(self.data_numpy[pos[1], pos[0]]) def __setitem__(self, pos, value): """ Example usage: self._game_info.pathing_grid[Point2((20, 20))] = 255 """ @@ -44,7 +46,7 @@ def __setitem__(self, pos, value): assert 0 <= pos[1] < self.height, f"y is {pos[1]}, self.height is {self.height}" assert 0 <= value < 256, f"value is {value}, it should be between 0 and 255" assert isinstance(value, int), f"value is of type {type(value)}, it should be an integer" - self.data_numpy[pos[0], pos[1]] = value + self.data_numpy[pos[1], pos[0]] = value def is_set(self, p): return self[p] != 0 @@ -99,3 +101,8 @@ def save_image(self, filename): im = Image.new("RGB", (self.width, self.height)) im.putdata(data) im.save(filename) + + def plot(self): + import matplotlib.pyplot as plt + plt.imshow(self.data_numpy, origin="lower") + plt.show() diff --git a/test/pickle_data/Automaton LE.pkl b/test/pickle_data/Automaton LE.pkl index 4e47c9cca..1d0c630ec 100644 Binary files a/test/pickle_data/Automaton LE.pkl and b/test/pickle_data/Automaton LE.pkl differ diff --git a/test/pickle_data/Blueshift LE.pkl b/test/pickle_data/Blueshift LE.pkl index b8c83a424..ca3ab95de 100644 Binary files a/test/pickle_data/Blueshift LE.pkl and b/test/pickle_data/Blueshift LE.pkl differ diff --git a/test/pickle_data/Cerulean Fall LE.pkl b/test/pickle_data/Cerulean Fall LE.pkl index f427d0405..32c4f0a9c 100644 Binary files a/test/pickle_data/Cerulean Fall LE.pkl and b/test/pickle_data/Cerulean Fall LE.pkl differ diff --git a/test/pickle_data/Darkness Sanctuary LE.pkl b/test/pickle_data/Darkness Sanctuary LE.pkl index 3b39fd4a5..c70590934 100644 Binary files a/test/pickle_data/Darkness Sanctuary LE.pkl and b/test/pickle_data/Darkness Sanctuary LE.pkl differ diff --git a/test/pickle_data/Kairos Junction LE.pkl b/test/pickle_data/Kairos Junction LE.pkl index 3debdf40d..d8931a25a 100644 Binary files a/test/pickle_data/Kairos Junction LE.pkl and b/test/pickle_data/Kairos Junction LE.pkl differ diff --git a/test/pickle_data/Old Sunshine.pkl b/test/pickle_data/Old Sunshine.pkl index 33359bf46..8adfa5689 100644 Binary files a/test/pickle_data/Old Sunshine.pkl and b/test/pickle_data/Old Sunshine.pkl differ diff --git a/test/pickle_data/Para Site LE.pkl b/test/pickle_data/Para Site LE.pkl index a0b0277d2..46e512cf1 100644 Binary files a/test/pickle_data/Para Site LE.pkl and b/test/pickle_data/Para Site LE.pkl differ diff --git a/test/pickle_data/Port Aleksander LE.pkl b/test/pickle_data/Port Aleksander LE.pkl index f26dd8c1b..9321db7c1 100644 Binary files a/test/pickle_data/Port Aleksander LE.pkl and b/test/pickle_data/Port Aleksander LE.pkl differ diff --git a/test/pickle_data/STC - Primus Q-9.pkl b/test/pickle_data/STC - Primus Q-9.pkl index 631c9f864..1f0243cbc 100644 Binary files a/test/pickle_data/STC - Primus Q-9.pkl and b/test/pickle_data/STC - Primus Q-9.pkl differ diff --git a/test/pickle_data/Sanglune.pkl b/test/pickle_data/Sanglune.pkl index 9970f98b6..f9ade1cdf 100644 Binary files a/test/pickle_data/Sanglune.pkl and b/test/pickle_data/Sanglune.pkl differ diff --git a/test/pickle_data/The Timeless Wild [PLX].pkl b/test/pickle_data/The Timeless Wild [PLX].pkl index e53387482..57bb8a025 100644 Binary files a/test/pickle_data/The Timeless Wild [PLX].pkl and b/test/pickle_data/The Timeless Wild [PLX].pkl differ diff --git a/test/pickle_data/Urzagol [PLX].pkl b/test/pickle_data/Urzagol [PLX].pkl index 36bcb6048..bcb6aa4bc 100644 Binary files a/test/pickle_data/Urzagol [PLX].pkl and b/test/pickle_data/Urzagol [PLX].pkl differ diff --git a/test/pickle_data/[TLMC10] Artana.pkl b/test/pickle_data/[TLMC10] Artana.pkl index 940d2034a..94cda6b89 100644 Binary files a/test/pickle_data/[TLMC10] Artana.pkl and b/test/pickle_data/[TLMC10] Artana.pkl differ diff --git a/test/pickle_data/[TLMC10] Digital Frontier.pkl b/test/pickle_data/[TLMC10] Digital Frontier.pkl index dfe5a2cbc..fb1d2fef4 100644 Binary files a/test/pickle_data/[TLMC10] Digital Frontier.pkl and b/test/pickle_data/[TLMC10] Digital Frontier.pkl differ diff --git a/test/pickle_data/[TLMC10] Treachery.pkl b/test/pickle_data/[TLMC10] Treachery.pkl index 4744cf0c1..4551300b2 100644 Binary files a/test/pickle_data/[TLMC10] Treachery.pkl and b/test/pickle_data/[TLMC10] Treachery.pkl differ diff --git a/test/pickle_data/[TLMC11] Crystal Cavern.pkl b/test/pickle_data/[TLMC11] Crystal Cavern.pkl index 851e8c1d0..aaef4b5d3 100644 Binary files a/test/pickle_data/[TLMC11] Crystal Cavern.pkl and b/test/pickle_data/[TLMC11] Crystal Cavern.pkl differ diff --git a/test/pickle_data/[TLMC11] Reminiscence.pkl b/test/pickle_data/[TLMC11] Reminiscence.pkl index 2a58683b1..9181d24b6 100644 Binary files a/test/pickle_data/[TLMC11] Reminiscence.pkl and b/test/pickle_data/[TLMC11] Reminiscence.pkl differ diff --git a/test/pickle_data/[TLMC12] Acropolis.pkl b/test/pickle_data/[TLMC12] Acropolis.pkl index 13cf9162b..97fc81def 100644 Binary files a/test/pickle_data/[TLMC12] Acropolis.pkl and b/test/pickle_data/[TLMC12] Acropolis.pkl differ diff --git a/test/pickle_data/[TLMC12] Bandwidth.pkl b/test/pickle_data/[TLMC12] Bandwidth.pkl index 3552d5b36..c9e90ba53 100644 Binary files a/test/pickle_data/[TLMC12] Bandwidth.pkl and b/test/pickle_data/[TLMC12] Bandwidth.pkl differ diff --git a/test/pickle_data/[TLMC12] Ephemeron.pkl b/test/pickle_data/[TLMC12] Ephemeron.pkl index 4b1aec1ca..d4ac4f1e7 100644 Binary files a/test/pickle_data/[TLMC12] Ephemeron.pkl and b/test/pickle_data/[TLMC12] Ephemeron.pkl differ diff --git a/test/pickle_data/[TLMC12] Triton.pkl b/test/pickle_data/[TLMC12] Triton.pkl index 2b7731590..a3dd448dc 100644 Binary files a/test/pickle_data/[TLMC12] Triton.pkl and b/test/pickle_data/[TLMC12] Triton.pkl differ diff --git a/test/test_pickled_data.py b/test/test_pickled_data.py index bf6f509f6..791c045c4 100644 --- a/test/test_pickled_data.py +++ b/test/test_pickled_data.py @@ -358,7 +358,7 @@ def test_unit(self, bot: BotAI): assert not townhall.is_blip assert not scv.is_powered assert not townhall.is_powered - assert not scv.is_active + assert scv.is_active assert not townhall.is_active assert not scv.mineral_contents assert not townhall.mineral_contents