Source code for pathfinding3d.core.node

import dataclasses
from typing import List, Optional, Tuple


[docs]@dataclasses.dataclass class Node: """ Basic node class, saves calculated values for pathfinding Attributes ---------- h : float The cost from this node to the goal (for A* including the heuristic). g : float The cost from the start node to this node. f : float The overall cost for a path using this node (f = g + h). opened : int The number of times this node has been opened. closed : bool Whether this node is closed. parent : Optional[Node] The parent node of this node. retain_count : int Used for recursion tracking of IDA*. tested : bool Used for IDA* and Jump-Point-Search. """ __slots__ = ["h", "g", "f", "opened", "closed", "parent", "retain_count", "tested"]
[docs] def __init__(self): self.cleanup()
def __lt__(self, other: "Node") -> bool: return self.f < other.f
[docs] def cleanup(self): """ Reset all calculated values, fresh start for pathfinding """ # cost from this node to the goal (for A* including the heuristic) self.h = 0.0 # cost from the start node to this node # (calculated by distance function, e.g. including diagonal movement) self.g = 0.0 # overall cost for a path using this node (f = g + h ) self.f = 0.0 self.opened = 0 self.closed = False # used for backtracking to the start point self.parent = None # used for recurion tracking of IDA* self.retain_count = 0 # used for IDA* and Jump-Point-Search self.tested = False
[docs]@dataclasses.dataclass class GridNode(Node): """ Basic node in a grid. Attributes ---------- x : int The x coordinate of the node. y : int The y coordinate of the node. z : int The z coordinate of the node. walkable : bool Whether this node can be walked through. weight : float The weight of the node. grid_id : Optional[int] The id of the grid this node belongs to. connections : List[GridNode] The nodes this node is connected to. """ # Coordinates x: int = 0 y: int = 0 z: int = 0 # Wether this node can be walked through. walkable: bool = True # used for weighted algorithms weight: float = 1.0 # grid_id is used if we have more than one grid, # normally we just count our grids by number # but you can also use a string here. # Set it to None if you only have one grid. grid_id: Optional[int] = None connections: List["GridNode"] = dataclasses.field(default_factory=list) def __post_init__(self): super().__init__() # for heap self.identifier: Tuple = ( (self.x, self.y, self.z) if self.grid_id is None else (self.x, self.y, self.z, self.grid_id) ) def __iter__(self): yield self.x yield self.y yield self.z if self.grid_id is not None: yield self.grid_id
[docs] def connect(self, other_node: "GridNode"): """ Connect this node to another node. Parameters ---------- other_node : GridNode The node to connect to. """ self.connections.append(other_node)