### pathfind example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Example usage of pathfind with a grid, start and goal points, large=False, smoothing=False, and sensitivity 3. If no grid is provided, a fresh grid is requested from Pather. ```python >>> my_grid = self.get_pyastar_grid() >>> # start / goal could be any tuple / Point2 >>> st, gl = (50,75) , (100,100) >>> path = self.pathfind(start=st,goal=gl,grid=my_grid, large=False, smoothing=False, sensitivity=3) ``` -------------------------------- ### Install from requirements Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/gettingstarted/index.rst.txt Install dependencies using the requirements file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install the package Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/gettingstarted/index.rst.txt Install the package using pip. ```bash pip install . ``` -------------------------------- ### Get Starting Region with MapData.where_all Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/basics/index.rst.txt Use MapData.where_all to find the region containing a given position, such as the bot's starting base. The example shows that the returned list contains a Region object, and indexing [0] retrieves the first region. ```python >>> my_base_raw_location = self.bot.townhalls[0].position >>> my_region = self.where_all(my_base_raw_location)[0] >>> my_region Region 3 ``` -------------------------------- ### pathfind_pyastar example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Example usage of pathfind_pyastar with a grid, start and goal points, diagonal movement enabled, and sensitivity 3. If no grid is provided, a fresh grid is requested from Pather. ```python >>> 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) ``` -------------------------------- ### Install SC2MapAnalyzer with pip install . Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/gettingstarted/index.html Runs after cloning the repository to install the package inside the virtual environment. ```bash pip install . ``` -------------------------------- ### Install SC2MapAnalyzer requirements with pip install -r requirements.txt Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/gettingstarted/index.html Alternative installation using the requirements.txt file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install for development Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/gettingstarted/index.rst.txt Install the package in editable mode with development dependencies for testing or contributing. ```bash pip install -e .[dev] ``` -------------------------------- ### where_all connected regions example Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/MapAnalyzer/MapData/index.html Example showing how to get the natural region using connected_regions property. ```python >>> # now it is very easy to know which region is the enemy's natural >>> # connected_regions is a property of a Region >>> enemy_natural_region = enemy_main_base_region.connected_regions[0] >>> # will return Region 1 or 6 for goldenwall depending on starting position ``` -------------------------------- ### get_air_vs_ground_grid example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Example usage of get_air_vs_ground_grid. Requesting a grid with default_weight of 1 is pointless and will result in get_clean_air_grid. ```python >>> air_vs_ground_grid = self.get_air_vs_ground_grid() ``` -------------------------------- ### pathfind example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/source/MapAnalyzer/MapData/index.rst.txt Retrieves a pyastar grid and calls pathfind with optional large and smoothing parameters to control path finding for different unit sizes. ```python my_grid = self.get_pyastar_grid() # start / goal could be any tuple / Point2 st, gl = (50,75) , (100,100) path = self.pathfind(start=st,goal=gl,grid=my_grid, large=False, smoothing=False, sensitivity=3) ``` -------------------------------- ### Install SC2MapAnalyzer development dependencies with pip install -e .[dev] Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/gettingstarted/index.html Use this option to contribute to the project or run tests locally. ```bash pip install -e .[dev] ``` -------------------------------- ### pathfind_pyastar(start, goal, grid=None, allow_diagonal=False, sensitivity=1) Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/MapData.html Finds the lowest cost path from start to goal using the provided grid or a fresh grid if none given. Supports diagonal movement and path sensitivity slicing. ```APIDOC ## pathfind_pyastar(start, goal, grid=None, allow_diagonal=False, sensitivity=1) ### Description Returns the path with the lowest cost (sum) given a weighted array (`grid`), `start`, and `goal`. If no `grid` is provided, a fresh grid is requested from the Pather. If no path is possible, returns `None`. ### Method N/A (SDK method) ### Endpoint N/A ### Parameters - **start** (Union[Tuple[float,float], Point2]) - Required - Starting coordinate. - **goal** (Union[Tuple[float,float], Point2]) - Required - Goal coordinate. - **grid** (ndarray) - Optional - Weighted grid to use; if None, a fresh grid is obtained. - **allow_diagonal** (bool) - Optional - Whether diagonal movement is allowed. Default False. Enabling may incur a slight performance penalty. - **sensitivity** (int) - Optional - Slices the result path, equivalent to `path[::sensitivity]`. Default 1. ### Request Example ```python path = self.pathfind_pyastar(start=(50,75), goal=(100,100), grid=my_grid, allow_diagonal=True, sensitivity=3) ``` ### Response Returns `Optional[List[Point2]]` - the path as a list of Point2 objects, or `None` if no path found. ``` -------------------------------- ### MapAnalyzer.utils Imports and Setup Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/utils.html Initial imports and type definitions required for the MapAnalyzer.utils module. ```python import lzma import os import pickle import numpy as np from typing import List, Optional, TYPE_CHECKING, Union from s2clientprotocol.sc2api_pb2 import Response, ResponseObservation from sc2.bot_ai import BotAI from sc2.game_data import GameData from sc2.game_info import GameInfo, Ramp from sc2.game_state import GameState from sc2.position import Point2 from sc2.unit import Unit from MapAnalyzer.constructs import MDRamp, VisionBlockerArea from .cext import CMapChoke from .destructibles import * from .settings import ROOT_DIR if TYPE_CHECKING: from MapAnalyzer.MapData import MapData ``` -------------------------------- ### where_all example Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/MapAnalyzer/MapData/index.html Example usage of where_all to query which region contains a given point. ```python >>> # query in which region is the enemy main >>> position = self.bot.enemy_start_locations[0].position >>> all_polygon_areas_in_position = self.where_all(position) >>> all_polygon_areas_in_position [Region 4] ``` -------------------------------- ### where_all result extraction example Source: https://eladyaniv01.github.io/SC2MapAnalysis/source/MapAnalyzer/MapData/index.html Example showing how to extract the region from the result of where_all and access connected regions. ```python >>> enemy_main_base_region = all_polygon_areas_in_position[0] >>> enemy_main_base_region Region 4 ``` -------------------------------- ### Example: draw_influence_in_game with get_pyastar_grid and add_cost Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Shows how to prepare a grid with a default weight, add a cost at a point, and then call draw_influence_in_game. The final call is commented out for doctest purposes. ```python >>> self.ground_grid = self.get_pyastar_grid(default_weight=1) >>> self.ground_grid = self.add_cost((100, 100), radius=15, grid=self.ground_grid, weight=50) >>> # self.draw_influence_in_game(self.ground_grid, lower_threshold=1) # commented out for doctest ``` -------------------------------- ### find_lowest_cost_points example with output Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Calls find_lowest_cost_points with an air-vs-ground grid, origin (100, 80), and radius 10, then shows the returned list of lowest-cost Point2 coordinates. ```python my_grid = self.get_air_vs_ground_grid() position = (100, 80) my_radius = 10 self.find_lowest_cost_points(from_pos=position, radius=my_radius, grid=my_grid) ``` ```python [(90, 80), (91, 76), (91, 77), (91, 78), (91, 79), (91, 80), (91, 81), (92, 74), (92, 75), (92, 76), (92, 77), (92, 78), (92, 79), (92, 80), (92, 81), (93, 73), (93, 74), (93, 75), (93, 76), (93, 77), (93, 78), (93, 79), (93, 80), (93, 81), (94, 72), (94, 73), (94, 74), (94, 75), (94, 76), (94, 77), (95, 73), (95, 74), (95, 75), (95, 76), (96, 74), (96, 75), (97, 74), (97, 75), (98, 74), (98, 75), (99, 74), (99, 75), (100, 74), (100, 75), (101, 74), (101, 75), (102, 74), (102, 75), (103, 74), (103, 75), (104, 74), (104, 75), (105, 74), (105, 75), (106, 74), (106, 75), (107, 74), (107, 75), (108, 74), (108, 75)] ``` -------------------------------- ### Calculate best_siege_console: closest_toward_point with example coordinates and expected output: (49, peak2) Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/source/MapAnalyzer/MapData/index.rst.txt Example usage closest_towards_point with enemy army at coordinates (50, obtaining the player's base location via self.best.townhownshows the expected output of (49, 52) tanks positioning. ```python >>> from typing import * >>> from sc2.position import Point2 # assumed context for clarity, actual code as in source follows: >>> enemy_1 = Point2((50,50)) placeholder for enemy army position (50, closest_tower) (50,50,50) (50, meh (50,50) (50, >>> my_base_location = self.bot.townhollows[0].position >>> my_typical_region = self.where_all(my_baseLocation)[0] >>> best_simulated_region = closest_t ``` -------------------------------- ### Plot and Debug the Pather - In Game Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/PathFinding/index.rst.txt This recipe shows how to get an air vs ground grid and optionally draw influence in-game for debugging pathfinding. ```APIDOC ## Plot and Debug the Pather - In Game ### Description This recipe demonstrates how to obtain an air vs ground grid and optionally draw the influence in-game for debugging pathfinding. ### Methods Used - MapData.get_air_vs_ground_grid - MapData.draw_influence_in_game (commented out in example) ### Code Example ```python grid = self.get_air_vs_ground_grid() # self.draw_influence_in_game(grid) # commented out to not fail doc tests ``` ``` -------------------------------- ### pathfind(start, goal, grid=None, large=False, smoothing=False, sensitivity=1) -> Union[List[Point2], None] Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/technical/api/MapAnalyzer/MapData/index.rst.html Finds the lowest-cost path using the standard pathfinding algorithm. Returns None if no path is possible. ```APIDOC ## pathfind(start, goal, grid=None, large=False, smoothing=False, sensitivity=1) -> Union[List[Point2], None] ### Description Finds the lowest-cost path using the standard pathfinding algorithm. Returns None if no path is possible. ### Method Function ### Signature `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) -> Union[List[Point2], None]` ### Parameters - **start** (Union[Tuple[float, float], Point2]) - Required - Starting position. - **goal** (Union[Tuple[float, float], Point2]) - Required - Goal position. - **grid** (Optional[ndarray]) - Optional - Weighted grid. If not provided, a fresh grid is requested from Pather. - **large** (bool) - Optional - If True, pathfinding accounts for large unit sizes (e.g., Thor, Ultralisk). Default False uses unit size 1. - **smoothing** (bool) - Optional - If True, attempts to skip waypoints when a straight line is better according to the influence grid. - **sensitivity** (int) - Optional - Slices the path: `result_path = path[::sensitivity]`. Useful to get every n-th point. ### Return Type Union[List[Point2], None] ### Example ``` >>> my_grid = self.get_pyastar_grid() >>> st, gl = (50,75) , (100,100) >>> path = self.pathfind(start=st,goal=gl,grid=my_grid, large=False, smoothing=False, sensitivity=3) ``` ### See Also - `MapData.get_pyastar_grid()` - `MapData.find_lowest_cost_points()` ``` -------------------------------- ### pathfind Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/MapAnalyzer/MapData/index.rst.txt Finds the path with the lowest cost from start to goal using a weighted grid. Supports large unit sizes, smoothing, and sensitivity slicing. Returns None if no path is possible. ```APIDOC ## pathfind(start, goal, grid=None, large=False, smoothing=False, sensitivity=1) ### Description Will return the path with lowest cost (sum) given a weighted array (grid), start, and goal. If no grid is provided, will request a fresh grid from the Pather class. Returns None if no path is possible. The sensitivity parameter indicates how to slice the path, similar to `result_path = path[::sensitivity]`. The large parameter determines whether pathing is done with large unit sizes (e.g., Thor, Ultralisk). When false, it uses unit size 1. Smoothing tries to skip all waypoints that can be skipped if taking a straight line forward is better according to the influence grid. ### Method This is a Python method, not an HTTP endpoint. ### Signature `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) -> Union[List[Point2], None]` ### Parameters - **start** (Union[Tuple[float, float], Point2]) - Required - The starting position. - **goal** (Union[Tuple[float, float], Point2]) - Required - The goal position. - **grid** (Optional[ndarray]) - Optional - The weighted grid for pathfinding. If not provided, a fresh grid is requested from the Pather class. - **large** (bool) - Optional - Whether to do pathfinding with large unit sizes. Defaults to False. If True, guarantees that a unit with size > 1 fits through the path. - **smoothing** (bool) - Optional - Whether to apply smoothing on the C side to skip unnecessary waypoints. Defaults to False. - **sensitivity** (int) - Optional - Determines how to slice the path (e.g., path[::sensitivity]). Defaults to 1. ### Return Value - **Union[List[Point2], None]** - The path as a list of Point2 objects, or None if no path is possible. ### Example ```python my_grid = self.get_pyastar_grid() st, gl = (50,75), (100,100) path = self.pathfind(start=st, goal=gl, grid=my_grid, large=False, smoothing=False, sensitivity=3) ``` ### See Also - get_pyastar_grid - find_lowest_cost_points ``` -------------------------------- ### get_climber_grid example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Requests a climber grid with default weight 1 for units that can climb, such as Reaper and Colossus. The grid is updated with nonpathables like structures and destructables. ```python updated_climber_grid = self.get_climber_grid(default_weight = 1) ``` -------------------------------- ### MapData source code: region grid and vision blockers setup Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/MapData.html Initializes the region grid using labeled array and computes vision blockers if present. Uses generate_binary_structure and ndlabel from scipy.ndimage. ```python s = generate_binary_structure(BINARY_STRUCTURE, BINARY_STRUCTURE) labeled_array, num_features = ndlabel(grid, structure=s) # for some operations the array must have same numbers or rows and cols, adding # zeros to fix that # rows, cols = labeled_array.shape # self.region_grid = np.append(labeled_array, np.zeros((abs(cols - rows), cols)), axis=0) self.region_grid = labeled_array.astype(int) self.regions_labels = np.unique(self.region_grid) vb_points = self._vision_blockers # some maps has no vision blockers if len(vb_points): vision_blockers_indices = self.points_to_indices(vb_points) vision_blockers_array = np.zeros(self.region_grid.shape, dtype="int") vision_blockers_array[vision_blockers_indices] = 1 vb_labeled_array, vb_num_features = ndlabel(vision_blockers_array) self.vision_blockers_grid = vb_labeled_array self.vision_blockers_labels = np.unique(vb_labeled_array) ``` -------------------------------- ### get_pyastar_grid examples Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Shows two ways to call get_pyastar_grid: one treating destructables as pathable (include_destructables=False) and one setting a custom default weight of 300. The first is the only known use case for include_destructables. ```python no_destructables_grid = self.get_pyastar_grid(default_weight = 1, include_destructables= False) ``` ```python # 2 set up a grid with default weight of 300 custom_weight_grid = self.get_pyastar_grid(default_weight = 300) ``` -------------------------------- ### Get Enemy Main and Natural Regions with connected_regions Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/basics/index.rst.txt Find the enemy main base region using MapData.where_all on the enemy start location, then use the Region.connected_regions property to get the natural region. The example shows that the natural region's label may vary based on positions. ```python >>> # query in which region is the enemy main >>> position = self.bot.enemy_start_locations[0].position >>> all_polygon_areas_in_position = self.where_all(position) >>> all_polygon_areas_in_position [Region 4] >>> enemy_main_base_region = all_polygon_areas_in_position[0] >>> enemy_main_base_region Region 4 >>> # now it is very easy to know which region is the enemy's natural >>> # connected_regions is a property of a Region >>> enemy_natural_region = enemy_main_base_region.connected_regions[0] # connected_regions is a property of a Region >>> enemy_natural_region.label == 6 or enemy_natural_region.label == 1 # doctest expects this to be true and it changes based on positions True ``` -------------------------------- ### Query regions at a specific position Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Example of querying which region contains the enemy's starting position and identifying connected regions. ```python >>> # query in which region is the enemy main >>> position = self.bot.enemy_start_locations[0].position >>> all_polygon_areas_in_position = self.where_all(position) >>> all_polygon_areas_in_position [Region 4] >>> enemy_main_base_region = all_polygon_areas_in_position[0] >>> enemy_main_base_region Region 4 >>> # now it is very easy to know which region is the enemy's natural >>> # connected_regions is a property of a Region >>> enemy_natural_region = enemy_main_base_region.connected_regions[0] >>> # will return Region 1 or 6 for goldenwall depending on starting position ``` -------------------------------- ### Explore Region Connectivity with connected_regions Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/basics/index.rst.txt Use the Region.connected_regions property to get a list of regions connected to a given region. The example sorts the list by label for deterministic doctest output. ```python >>> my_base_location = self.bot.townhalls[0].position >>> my_region = self.where_all(my_base_location)[0] >>> my_region Region 3 >>> # returns a list >>> my_region.connected_regions.sort(key=lambda x: x.label) # sorting for doctest >>> my_region.connected_regions [Region 0, Region 5] ``` -------------------------------- ### Clone and enter the repository Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/gettingstarted/index.rst.txt Clone the SC2MapAnalysis repository and navigate into the directory. ```bash git clone https://github.com/eladyaniv01/SC2MapAnalysis.git cd SC2MapAnalysis ``` -------------------------------- ### Pathfinding from main to enemy's main Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/PathFinding/index.rst.txt This recipe shows how to find a path from the player's main base to the enemy's main base using MapData.where_all and MapData.pathfind. ```APIDOC ## Pathfinding from main to enemy's main ### Description This recipe demonstrates how to find a path from the player's main base to the enemy's main base using the MapData.where_all and MapData.pathfind methods. ### Methods Used - MapData.where_all - MapData.pathfind ### Code Example ```python my_base_raw_location = self.bot.townhalls[0].position my_region = self.where_all(my_base_raw_location)[0] enemy_main_region = self.where_all(self.bot.enemy_start_locations[0].position)[0] start = my_region.center goal = enemy_main_region.center grid = self.get_pyastar_grid() path = self.pathfind(start=start, goal=goal, grid=grid, sensitivity=3) print(path) ``` ### Expected Output A list of coordinate tuples representing the path from start to goal. ``` -------------------------------- ### Module imports and tqdm initialization in MapAnalyzer.decorators Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/decorators.html Sets up imports, the `tqdm` partial with `dynamic_ncols=True`, and the `logger_wraps` decorator that logs function entry/exit at a given level. ```python import contextlib import functools import sys import threading from functools import partial from typing import Any, Callable, Dict, Optional, Tuple # import tqdm from loguru import logger from tqdm import tqdm as std_tqdm from tqdm.contrib import DummyTqdmFile tqdm = partial(std_tqdm, dynamic_ncols=True) def logger_wraps(*, entry=True, exit=True, level="INFO"): def wrapper(func): name = func.__name__ @functools.wraps(func) def wrapped(*args, **kwargs): logger_ = logger.opt(depth=1) if entry: logger_.log(level, "Entering '{}' (args={}, kwargs={})", name, args, kwargs) result = func(*args, **kwargs) if exit: logger_.log(level, "Exiting '{}' (result={})", name, result) return result return wrapped return wrapper ``` -------------------------------- ### draw_influence_in_game method with doctest example Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/MapData.html Draws influence (cost) values of a grid in game. The doctest example shows how to set up a ground grid with default weight and add cost, then call the method (commented out). Lower thresholds impact performance. ```python def draw_influence_in_game(self, grid: ndarray, lower_threshold: int = 1, upper_threshold: int = 1000, color: Tuple[int, int, int] = (201, 168, 79), size: int = 13) -> None: """ :rtype: None Draws influence (cost) values of a grid in game. Caution: Setting the lower threshold too low impacts performance since almost every value will get drawn. It's recommended that this is set to the relevant grid's default weight value. Example: >>> self.ground_grid = self.get_pyastar_grid(default_weight=1) >>> self.ground_grid = self.add_cost((100, 100), radius=15, grid=self.ground_grid, weight=50) >>> # self.draw_influence_in_game(self.ground_grid, lower_threshold=1) # commented out for doctest See Also: * :meth:`.MapData.get_pyastar_grid` * :meth:`.MapData.get_climber_grid` * :meth:`.MapData.get_clean_air_grid` * :meth:`.MapData.get_air_vs_ground_grid` * :meth:`.MapData.add_cost` """ self.debugger.draw_influence_in_game(self.bot, grid, lower_threshold, upper_threshold, color, size) ``` -------------------------------- ### Pathfind with MapData.pathfind Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/MapData.html Finds the lowest-cost path between start and goal using a provided or freshly requested grid. Returns None if no path exists. The sensitivity parameter slices the result (e.g., path[::sensitivity]). Also supports large reset and smoothing options. ```Python return self.pather.pathfind_pyastar(start=start, goal=goal, grid=grid, allow_diagonal=allow_diagonal, sensitivity=sensitivity) [docs] 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]]: """ :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`` ``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 ``` -------------------------------- ### Get wall-off building positions in a Region Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/howto/Buildings/index.rst.txt Shows how to obtain a Region from a base location, access its ramps, and retrieve buildable points that are the wall-off positions. It includes steps to get the raw location of a base, the region containing it, sort ramps by area, and extract buildable points using the buildables.points property. ```python >>> my_base_raw_location = self.bot.townhalls[0].position >>> my_region = self.where_all(my_base_raw_location)[0] >>> my_region Region 3 >>> # in most cases region will have only one ramp, but there are cases of more than one >>> # my_region.region_ramps will evaluate to ~ [, ] >>> my_region.region_ramps.sort(key=lambda r: r.area) >>> my_region_ramp = my_region.region_ramps[0] >>> # my_region_ramp ~ >>> # my_region_ramp.buildables ~ >>> # you can also see that these buildable points only belong >>> # to this specific Polygon, in our case MDRamp >>> # my_region_ramp.buildables.polygon ~ >>> # low buildable percent makes sense, most of the ramp's Polygon is not buildable >>> # my_region_ramp.buildables.free_pct ~ 0.22413793103448276 >>> # finally, the buildable points, which are the ramp wall-off positions >>> my_region_ramp.buildables.points # finally, the buildable points, which are the ramp wall-off positions [(42, 43), (46, 47), (44, 45), (47, 38), (49, 40), (41, 42), (43, 44), (48, 39), (46, 37), (45, 46), (41, 41), (50, 41), (46, 46)] >>> # lets plot those buildable points >>> x,y = zip(*my_region_ramp.buildables.points) >>> # self.debugger.scatter(x,y,color="red",marker=r"$\heartsuit$", s=500, edgecolors="r") >>> # self.show() ``` -------------------------------- ### _calc_grid method - convert placement grid and mark resource blockers Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer/MapData.html Converts the placement grid to a binary grid with holes filled, then marks resource blockers and their neighbors as barriers. ```python def _calc_grid(self) -> None: # converting the placement grid to our own kind of grid # cleaning the grid and then searching for 2x2 patterned regions grid = binary_fill_holes(self.placement_arr).astype(int) # for our grid, mineral walls are considered as a barrier between regions for point in self.resource_blockers: grid[int(point[0])][int(point[1])] = 0 for n in point.neighbors4: point_ = Point2((n.rounded[0], n.rounded[1])) if point_[0] < grid.shape[1] and point_[1] < grid.shape[0]: grid[int(point_[1])][int(point_[0])] = 0 ``` -------------------------------- ### MapAnalyzer.exceptions.PatherNoPointsException Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/technical/api/MapAnalyzer/exceptions/index.rst.html Custom exception class raised when the pather has no points. It inherits from BaseException and requires start and goal parameters. ```APIDOC ## PatherNoPointsException ### Description Custom exception class raised when the pather has no points. It inherits from BaseException and requires start and goal parameters. ### Constructor `PatherNoPointsException(start, goal)` ### Parameters - **start** - The starting point. - **goal** - The goal point. ### Inherits - `BaseException` ``` -------------------------------- ### pathfind_pyastar Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/source/MapAnalyzer/MapData/index.rst.txt Finds the path with the lowest cost from start to goal using the pyastar algorithm on a weighted grid. Returns None if no path is possible. ```APIDOC ## pathfind_pyastar(start, goal, grid=None, allow_diagonal=False, sensitivity=1) ### Description Will return the path with lowest cost (sum) given a weighted array (grid), start, and goal. If no grid is provided, will request a fresh grid from the Pather class. Returns None if no path is possible. The sensitivity parameter indicates how to slice the path, similar to `result_path = path[::sensitivity]`, which is useful for getting every n-th point. Allow_diagonal=True results in a slight performance penalty but naturally generates shorter paths. ### Method This is a Python method, not an HTTP endpoint. ### Signature `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) -> Union[List[Point2], None]` ### Parameters - **start** (Union[Tuple[float, float], Point2]) - Required - The starting position. - **goal** (Union[Tuple[float, float], Point2]) - Required - The goal position. - **grid** (Optional[ndarray]) - Optional - The weighted grid for pathfinding. If not provided, a fresh grid is requested from the Pather class. - **allow_diagonal** (bool) - Optional - Whether to allow diagonal movement. Defaults to False. Setting to True results in a slight performance penalty but can generate shorter paths. - **sensitivity** (int) - Optional - Determines how to slice the path (e.g., path[::sensitivity]). Defaults to 1. ### Return Value - **Union[List[Point2], None]** - The path as a list of Point2 objects, or None if no path is possible. ### Example ```python my_grid = self.get_pyastar_grid() st, gl = (50,75), (100,100) path = self.pathfind_pyastar(start=st, goal=gl, grid=my_grid, allow_diagonal=True, sensitivity=3) ``` ### See Also - get_pyastar_grid - find_lowest_cost_points ``` -------------------------------- ### MapData.pathfind_pyastar Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/index.rst.txt Finds the path with lowest cost given a weighted grid, start, and goal. Returns a list of Point2 or None if no path is possible. ```APIDOC ## MapData.pathfind_pyastar ### Description Will return the path with lowest cost (sum) given a weighted array (grid), start, and goal. If no grid is provided, requests a fresh grid from Pather. If no path is possible, returns None. ### Method Method call ### Endpoint MapData.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) ### Parameters #### Parameters - **start** (Union[Tuple[float, float], Point2]) - Required - Starting position. - **goal** (Union[Tuple[float, float], Point2]) - Required - Goal position. - **grid** (Optional[ndarray]) - Optional - Weighted grid. If not provided, a fresh grid is requested from Pather. - **allow_diagonal** (bool) - Optional - Whether diagonal movement is allowed. Default is False. Enabling may cause a slight performance penalty but can generate shorter paths. - **sensitivity** (int) - Optional - Slices the path as path[::sensitivity]. Default is 1. ### Return Type Union[List[Point2], None] ### Example >>> my_grid = self.get_pyastar_grid() >>> st, gl = (50,75) , (100,100) >>> path = self.pathfind_pyastar(start=st,goal=gl,grid=my_grid,allow_diagonal=True, sensitivity=3) ### See Also - MapData.get_pyastar_grid - MapData.find_lowest_cost_points ``` -------------------------------- ### MapData.__init__ Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/MapData/index.rst.txt Constructor for the MapData class, the entry point for users. Initializes the object with a BotAI instance and optional configuration parameters. ```APIDOC ## MapData.__init__ ### Description Constructor for the MapData class, the entry point for users. Initializes the object with a BotAI instance and optional configuration parameters. ### Method Constructor ### Signature MapData(bot: BotAI, loglevel: str = 'ERROR', arcade: bool = False, corner_distance: int = CORNER_MIN_DISTANCE) ### Parameters - **bot** (BotAI) - Required - The BotAI instance. - **loglevel** (str) - Optional - Logging level, default 'ERROR'. - **arcade** (bool) - Optional - Whether in arcade mode, default False. - **corner_distance** (int) - Optional - Corner distance, default CORNER_MIN_DISTANCE. ### Returns None ``` -------------------------------- ### MapAnalyzer module imports and version detection Source: https://eladyaniv01.github.io/SC2MapAnalysis/_modules/MapAnalyzer.html Imports core classes from the package and attempts to retrieve the installed version of 'sc2mapanalyzer', falling back to 'dev' if not found. ```python # flake8: noqa from .MapData import MapData from .Polygon import Polygon from .Region import Region from .constructs import ChokeArea, MDRamp, VisionBlockerArea from pkg_resources import get_distribution, DistributionNotFound try: __version__ = get_distribution('sc2mapanalyzer') except DistributionNotFound: __version__ = 'dev' ``` -------------------------------- ### MapAnalyzer.constructs Classes Source: https://eladyaniv01.github.io/SC2MapAnalysis/_sources/_sources/technical/api/MapAnalyzer/constructs/index.rst.txt Documentation for the classes in the MapAnalyzer.constructs module, including their constructors, methods, and properties. ```APIDOC ## [Class] MapAnalyzer.constructs.ChokeArea ### Description Base class for all chokes. ### Constructor - **array** (np.ndarray) - Required - The array representing the choke area. - **map_data** (MapData) - Required - The map data object. ### Inherits - MapAnalyzer.Polygon.Polygon ``` ```APIDOC ## [Class] MapAnalyzer.constructs.RawChoke ### Description Chokes found in the C extension where the terrain generates a choke point. ### Constructor - **array** (np.ndarray) - Required - The array representing the choke area. - **map_data** (MapData) - Required - The map data object. - **raw_choke** (CMapChoke) - Required - The raw choke object from the C extension. ### Inherits - MapAnalyzer.constructs.ChokeArea ``` ```APIDOC ## [Class] MapAnalyzer.constructs.MDRamp ### Description Wrapper for sc2.game_info.Ramp, responsible for calculating the relevant Region. ### Constructor - **map_data** (MapData) - Required - The map data object. - **array** (np.ndarray) - Required - The array representing the ramp area. - **ramp** (sc2Ramp) - Required - The SC2 ramp object. ### Inherits - MapAnalyzer.constructs.ChokeArea ### Methods #### closest_region(self, region_list) Will return the closest region with respect to self. #### set_regions(self) Method for calculating the relevant Region. #### top_center(self) (property) Alerts when sc2 fails to provide a top_center, and fallback to center. #### bottom_center(self) (property) Alerts when sc2 fails to provide a bottom_center, and fallback to center. ``` ```APIDOC ## [Class] MapAnalyzer.constructs.VisionBlockerArea ### Description VisionBlockerArea are areas containing tiles that hide the units that stand in it (for example, bushes). Units that attack from within a VisionBlockerArea cannot be targeted by units that do not stand inside. ### Constructor - **map_data** (MapData) - Required - The map data object. - **array** (np.ndarray) - Required - The array representing the vision blocker area. ### Inherits - MapAnalyzer.constructs.ChokeArea ```