diff --git a/MapAnalyzer/Debugger.py b/MapAnalyzer/Debugger.py index b0cc701..3b5de62 100644 --- a/MapAnalyzer/Debugger.py +++ b/MapAnalyzer/Debugger.py @@ -318,55 +318,6 @@ def plot_influenced_path_nydus(self, start: Union[Tuple[float, float], Point2], plt.title(f"{name}", fontdict=fontdict, loc='right') plt.grid() - def plot_influenced_path_pyastar(self, start: Union[Tuple[int, int], Point2], - goal: Union[Tuple[int, int], Point2], - weight_array: ndarray, - allow_diagonal=False, - name: Optional[str] = None, - fontdict: dict = None) -> None: - import matplotlib.pyplot as plt - from mpl_toolkits.axes_grid1 import make_axes_locatable - from matplotlib.cm import ScalarMappable - if not fontdict: - fontdict = {"family": "serif", "weight": "bold", "size": 20} - plt.style.use(["ggplot", "bmh"]) - org = "lower" - if name is None: - name = self.map_data.map_name - arr = weight_array.copy() - path = self.map_data.pathfind_pyastar(start, goal, - grid=arr, - sensitivity=1, - allow_diagonal=allow_diagonal) - ax: plt.Axes = plt.subplot(1, 1, 1) - if path is not None: - path = np.flipud(path) # for plot align - logger.info("Found") - x, y = zip(*path) - ax.scatter(x, y, s=3, c='green') - else: - logger.info("Not Found") - - x, y = zip(*[start, goal]) - ax.scatter(x, y) - - influence_cmap = plt.cm.get_cmap("afmhot") - ax.text(start[0], start[1], f"Start {start}") - ax.text(goal[0], goal[1], f"Goal {goal}") - ax.imshow(self.map_data.path_arr, alpha=0.5, origin=org) - ax.imshow(self.map_data.terrain_height, alpha=0.5, origin=org, cmap='bone') - arr = np.where(arr == np.inf, 0, arr).T - ax.imshow(arr, origin=org, alpha=0.3, cmap=influence_cmap) - divider = make_axes_locatable(ax) - cax = divider.append_axes("right", size="5%", pad=0.05) - sc = ScalarMappable(cmap=influence_cmap) - sc.set_array(arr) - sc.autoscale() - cbar = plt.colorbar(sc, cax=cax) - cbar.ax.set_ylabel('Pathing Cost', rotation=270, labelpad=25, fontdict=fontdict) - plt.title(f"{name}", fontdict=fontdict, loc='right') - plt.grid() - @staticmethod def draw_influence_in_game(bot: BotAI, grid: np.ndarray, diff --git a/MapAnalyzer/MapData.py b/MapAnalyzer/MapData.py index 69a1de0..be732c4 100644 --- a/MapAnalyzer/MapData.py +++ b/MapAnalyzer/MapData.py @@ -87,7 +87,6 @@ def __init__(self, bot: BotAI, loglevel: str = "ERROR", arcade: bool = False, self.pather = MapAnalyzerPather(self) self.connectivity_graph = None # set by pather - self.pyastar = self.pather.pyastar self.nonpathable_indices_stacked = self.pather.nonpathable_indices_stacked # compile @@ -267,54 +266,6 @@ def get_clean_air_grid(self, default_weight: float = 1) -> ndarray: """ return self.pather.get_clean_air_grid(default_weight=default_weight) - def pathfind_pyastar(self, start: Union[Tuple[float, float], Point2], goal: Union[Tuple[float, float], Point2], - grid: Optional[ndarray] = None, - allow_diagonal: bool = False, sensitivity: int = 1) -> Optional[List[Point2]]: - - """ - :rtype: Union[List[:class:`sc2.position.Point2`], None] - Will return the path with lowest cost (sum) given a weighted array (``grid``), ``start`` , and ``goal``. - - - **IF NO** ``grid`` **has been provided**, will request a fresh grid from :class:`.Pather` - - If no path is possible, will return ``None`` - - Tip: - ``sensitivity`` indicates how to slice the path, - just like doing: ``result_path = path[::sensitivity]`` - where ``path`` is the return value from this function - - this is useful since in most use cases you wouldn't want - to get each and every single point, - - getting every n-``th`` point works better in practice - - - Caution: - ``allow_diagonal=True`` will result in a slight performance penalty. - - `However`, if you don't over-use it, it will naturally generate shorter paths, - - by converting(for example) ``move_right + move_up`` into ``move_top_right`` etc. - - TODO: - more examples for different usages available - - Example: - >>> my_grid = self.get_pyastar_grid() - >>> # start / goal could be any tuple / Point2 - >>> st, gl = (50,75) , (100,100) - >>> path = self.pathfind_pyastar(start=st,goal=gl,grid=my_grid,allow_diagonal=True, sensitivity=3) - - See Also: - * :meth:`.MapData.get_pyastar_grid` - * :meth:`.MapData.find_lowest_cost_points` - - """ - return self.pather.pathfind_pyastar(start=start, goal=goal, grid=grid, allow_diagonal=allow_diagonal, - sensitivity=sensitivity) - def pathfind(self, start: Union[Tuple[float, float], Point2], goal: Union[Tuple[float, float], Point2], grid: Optional[ndarray] = None, large: bool = False, smoothing: bool = False, sensitivity: int = 1) -> Optional[List[Point2]]: @@ -935,27 +886,6 @@ def plot_map( logger.error(f"{inspect.stack()[1]}") self.debugger.plot_map(fontdict=fontdict, figsize=figsize) - def plot_influenced_path_pyastar(self, - - start: Union[Tuple[float, float], Point2], - goal: Union[Tuple[float, float], Point2], - weight_array: ndarray, - allow_diagonal=False, - name: Optional[str] = None, - fontdict: dict = None) -> None: - """ - - A useful debug utility method for experimenting with the :mod:`.Pather` module - - """ - - self.debugger.plot_influenced_path_pyastar(start=start, - goal=goal, - weight_array=weight_array, - name=name, - fontdict=fontdict, - allow_diagonal=allow_diagonal) - def plot_influenced_path(self, start: Union[Tuple[float, float], Point2], goal: Union[Tuple[float, float], Point2], diff --git a/MapAnalyzer/Pather.py b/MapAnalyzer/Pather.py index dcf201d..0295e97 100644 --- a/MapAnalyzer/Pather.py +++ b/MapAnalyzer/Pather.py @@ -1,7 +1,6 @@ from typing import List, Optional, Tuple, TYPE_CHECKING import numpy as np -import pyastar.astar_wrapper as pyastar from loguru import logger from numpy import ndarray @@ -46,7 +45,6 @@ class MapAnalyzerPather: def __init__(self, map_data: "MapData") -> None: self.map_data = map_data - self.pyastar = pyastar nonpathable_indices = np.where(self.map_data.bot.game_info.pathing_grid.data_numpy == 0) self.nonpathable_indices_stacked = np.column_stack( @@ -294,36 +292,6 @@ def get_pyastar_grid(self, default_weight: float = 1, include_destructables: boo grid = np.where(grid != 0, default_weight, np.inf).astype(np.float32) return grid - def pathfind_pyastar(self, start: Tuple[float, float], goal: Tuple[float, float], grid: Optional[ndarray] = None, - allow_diagonal: bool = False, sensitivity: int = 1) -> Optional[List[Point2]]: - - if grid is None: - logger.warning("Using the default pyastar grid as no grid was provided.") - grid = self.get_pyastar_grid() - - if start is not None and goal is not None: - start = round(start[0]), round(start[1]) - start = self.find_eligible_point(start, grid, self.terrain_height, 10) - goal = round(goal[0]), round(goal[1]) - goal = self.find_eligible_point(goal, grid, self.terrain_height, 10) - else: - logger.warning(PatherNoPointsException(start=start, goal=goal)) - return None - - # find_eligible_point didn't find any pathable nodes nearby - if start is None or goal is None: - return None - - path = self.pyastar.astar_path(grid, start=start, goal=goal, allow_diagonal=allow_diagonal) - if path is not None: - path = list(map(Point2, path))[::sensitivity] - - path.pop(0) - return path - else: - logger.debug(f"No Path found s{start}, g{goal}") - return None - def pathfind(self, start: Tuple[float, float], goal: Tuple[float, float], grid: Optional[ndarray] = None, large: bool = False, smoothing: bool = False, diff --git a/pf_perf.py b/pf_perf.py index 579c01f..8b022e9 100644 --- a/pf_perf.py +++ b/pf_perf.py @@ -55,18 +55,10 @@ def get_map_file_list() -> List[str]: for p in pts: arr = map_data.add_cost(p, r, arr) -start = time.perf_counter() -path = map_data.pathfind_pyastar(p0, p1, grid=arr, allow_diagonal=True) -pyastar_time = time.perf_counter() - start -print("pyastar time: {}".format(pyastar_time)) - -map_data.plot_influenced_path_pyastar(start=p0, goal=p1, weight_array=arr, allow_diagonal=True) - start = time.perf_counter() path2 = map_data.pathfind(p0, p1, grid=arr) ext_time = time.perf_counter() - start print("extension astar time: {}".format(ext_time)) -print("div: {}".format(ext_time / pyastar_time)) start = time.perf_counter() nydus_path = map_data.pathfind_with_nyduses(p0, p1, grid=arr)