-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathreaper_pathfinding.py
More file actions
99 lines (78 loc) · 3.4 KB
/
reaper_pathfinding.py
File metadata and controls
99 lines (78 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from sc2 import maps
from sc2.bot_ai import BotAI
from sc2.data import Difficulty, Race
from sc2.main import run_game
from sc2.player import Bot, Computer
from sc2.position import Point3
from sc2.unit import UnitTypeId
from mapsegmentation.map_segmentation import map_segmentation
from mapsegmentation.pathing import Djikstra
from mapsegmentation.dataclasses.passage import Ramp, Passage, ChokePoint, Cliff
import matplotlib.pyplot as plt
"""
This example shows how to use the MapSegmentation library to segment a map.
A Reaper is spawned and a path is calculated from its position to the enemy start location, avoiding ramps.
You can change the `avoid` parameter to exclude different types of passages or None to include all passages.
The map is segmented using the map_segmentation function, which returns a SegmentedMap object.
Debug drawing is used to show the path and the regions and passages of the map.
"""
class ReaperExample(BotAI):
def __init__(self):
super().__init__()
self.map = None
self.path = None
self.djikstra = None
async def on_start(self):
self.map = map_segmentation(self)
print("Close the plot window to continue")
plt.figure(figsize=(12, 6))
plt.axis("off")
plt.title(f"Map: {self.game_info.map_name}")
plt.subplot(1, 2, 2)
self.map.imshow("Segmented grid")
plt.subplot(1, 2, 1)
plt.imshow(self.game_info.placement_grid.data_numpy)
plt.title("Placement grid")
plt.show()
self.djikstra = Djikstra(self.map)
# spawn one reaper
await self.client.debug_create_unit([[UnitTypeId.REAPER, 1, self.start_location, 1]])
async def on_step(self, iteration):
# calculate path every 10 iterations
if iteration % 10 == 0 and self.units:
reaper = self.units(UnitTypeId.REAPER)
if reaper:
reaper = reaper[0]
position = reaper.position
target = self.enemy_start_locations[0]
# add avoid parameter to exclude different types of passages
path = self.djikstra(position, target, None, avoid=(Ramp,))
self.path = path
# debug drawing
if self.path:
for a, b in zip(self.path, self.path[1:]):
height_a = self.get_terrain_z_height(a) + 1
height_b = self.get_terrain_z_height(b) + 1
self.client.debug_line_out(Point3((a.x + 0.5, a.y + 0.5, height_a)), Point3((b.x + 0.5, b.y + 0.5, height_b)), color=(255, 0, 0))
map_center = self.game_info.map_center
height = self.get_terrain_z_height(map_center) + 2
self.client.debug_box2_out(Point3((map_center.x, map_center.y, height)), color=(0, 0, 255))
self.client.debug_text_world(f"Map center:\n{map_center}", Point3((map_center.x, map_center.y, height+1)), color=(255, 255, 255))
for passage in self.map.passages:
passage.draw_boxes(self.game_info, self.client)
for region in self.map.regions.values():
region.draw_center(self.game_info, self.client)
def main():
# EquilibriumAIE
# GoldenauraAIE
# GresvanAIE
# HardLeadAIE
# OceanbornAIE
# SiteDeltaAIE
run_game(
maps.get("GresvanAIE"),
[Bot(Race.Terran, ReaperExample()), Computer(Race.Protoss, Difficulty.Easy)],
realtime=True,
)
if __name__ == "__main__":
main()