Skip to content

Commit 04216ef

Browse files
authored
Merge pull request Dentosal#275 from tweakimp/develop
Use isdisjoint in buff checks, find vision blockers in game info
2 parents 63082ef + 1dc888e commit 04216ef

File tree

4 files changed

+42
-34
lines changed

4 files changed

+42
-34
lines changed

sc2/bot_ai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ def _prepare_first_step(self):
783783
"""First step extra preparations. Must not be called before _prepare_step."""
784784
if self.townhalls:
785785
self._game_info.player_start_location = self.townhalls.first.position
786-
self._game_info.map_ramps = self._game_info._find_ramps()
786+
self._game_info.map_ramps, self._game_info.vision_blockers = self._game_info._find_ramps_and_vision_blockers()
787787

788788
def _prepare_step(self, state, proto_game_info):
789789
# Set attributes from new state before on_step."""

sc2/game_info.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from collections import deque
22
from typing import Any, Deque, Dict, FrozenSet, Generator, List, Optional, Sequence, Set, Tuple, Union
33

4+
import numpy as np
5+
46
from .cache import property_immutable_cache, property_mutable_cache
57
from .pixel_map import PixelMap
68
from .player import Player
@@ -168,22 +170,38 @@ def __init__(self, proto):
168170
self.playable_area = Rect.from_proto(self._proto.start_raw.playable_area)
169171
self.map_center = self.playable_area.center
170172
self.map_ramps: List[Ramp] = None # Filled later by BotAI._prepare_first_step
173+
self.vision_blockers: Set[Point2] = None # Filled later by BotAI._prepare_first_step
171174
self.player_races: Dict[int, "Race"] = {
172175
p.player_id: p.race_actual or p.race_requested for p in self._proto.player_info
173176
}
174177
self.start_locations: List[Point2] = [Point2.from_proto(sl) for sl in self._proto.start_raw.start_locations]
175178
self.player_start_location: Point2 = None # Filled later by BotAI._prepare_first_step
176179

177-
def _find_ramps(self) -> List[Ramp]:
178-
"""Calculate (self.pathing_grid - self.placement_grid) (for sets) and then find ramps by comparing heights."""
180+
def _find_ramps_and_vision_blockers(self) -> Tuple[List[Ramp], Set[Point2]]:
181+
""" Calculate points that are pathable but not placeable.
182+
Then devide them into ramp points if not all points around the points are equal height
183+
and into vision blockers if they are. """
184+
185+
def equal_height_around(tile):
186+
# mask to slice array 1 around tile
187+
sliced = self.terrain_height.data_numpy[tile[1] - 1 : tile[1] + 2, tile[0] - 1 : tile[0] + 2]
188+
return len(np.unique(sliced)) == 1
189+
179190
map_area = self.playable_area
180-
rampPoints = (
181-
Point2((x, y))
182-
for x in range(map_area.x, map_area.x + map_area.width)
183-
for y in range(map_area.y, map_area.y + map_area.height)
184-
if self.placement_grid[(x, y)] == 0 and self.pathing_grid[(x, y)] == 1
185-
)
186-
return [Ramp(group, self) for group in self._find_groups(rampPoints)]
191+
# all points in the playable area that are pathable but not placable
192+
points = [
193+
Point2((b, a))
194+
for (a, b), value in np.ndenumerate(self.pathing_grid.data_numpy)
195+
if value == 1
196+
and map_area.x <= a < map_area.x + map_area.width
197+
and map_area.y <= b < map_area.y + map_area.height
198+
and self.placement_grid[(b, a)] == 0
199+
]
200+
# devide points into ramp points and vision blockers
201+
rampPoints = [point for point in points if not equal_height_around(point)]
202+
visionBlockers = set(point for point in points if equal_height_around(point))
203+
ramps = [Ramp(group, self) for group in self._find_groups(rampPoints)]
204+
return ramps, visionBlockers
187205

188206
def _find_groups(self, points: Set[Point2], minimum_points_per_group: int = 8):
189207
"""

sc2/unit.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -404,37 +404,27 @@ def buffs(self) -> Set:
404404
@property_immutable_cache
405405
def is_carrying_minerals(self) -> bool:
406406
""" Checks if a worker or MULE is carrying (gold-)minerals. """
407-
return any(
408-
buff in {BuffId.CARRYMINERALFIELDMINERALS, BuffId.CARRYHIGHYIELDMINERALFIELDMINERALS} for buff in self.buffs
409-
)
407+
return not {BuffId.CARRYMINERALFIELDMINERALS, BuffId.CARRYHIGHYIELDMINERALFIELDMINERALS}.isdisjoint(self.buffs)
410408

411409
@property_immutable_cache
412410
def is_carrying_vespene(self) -> bool:
413411
""" Checks if a worker is carrying vespene gas. """
414-
return any(
415-
buff
416-
in {
417-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGAS,
418-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASPROTOSS,
419-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASZERG,
420-
}
421-
for buff in self.buffs
422-
)
412+
return not {
413+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGAS,
414+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASPROTOSS,
415+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASZERG,
416+
}.isdisjoint(self.buffs)
423417

424418
@property_immutable_cache
425419
def is_carrying_resource(self) -> bool:
426420
""" Checks if a worker is carrying a resource. """
427-
return any(
428-
buff
429-
in {
430-
BuffId.CARRYMINERALFIELDMINERALS,
431-
BuffId.CARRYHIGHYIELDMINERALFIELDMINERALS,
432-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGAS,
433-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASPROTOSS,
434-
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASZERG,
435-
}
436-
for buff in self.buffs
437-
)
421+
return not {
422+
BuffId.CARRYMINERALFIELDMINERALS,
423+
BuffId.CARRYHIGHYIELDMINERALFIELDMINERALS,
424+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGAS,
425+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASPROTOSS,
426+
BuffId.CARRYHARVESTABLEVESPENEGEYSERGASZERG,
427+
}.isdisjoint(self.buffs)
438428

439429
@property_immutable_cache
440430
def detect_range(self) -> Union[int, float]:

test/test_pickled_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_bot_ai(self, bot: BotAI):
109109
assert bot.townhalls.random.position not in bot.enemy_start_locations
110110
assert bot.known_enemy_units == Units([])
111111
assert bot.known_enemy_structures == Units([])
112-
bot._game_info.map_ramps = bot._game_info._find_ramps()
112+
bot._game_info.map_ramps, bot._game_info.vision_blockers = bot._game_info._find_ramps_and_vision_blockers()
113113
assert bot.main_base_ramp # Test if any ramp was found
114114
# TODO: Cache all expansion positions for a map and check if it is the same
115115
assert len(bot.expansion_locations) >= 12

0 commit comments

Comments
 (0)