-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathnode.py
More file actions
116 lines (91 loc) · 2.78 KB
/
Copy pathnode.py
File metadata and controls
116 lines (91 loc) · 2.78 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from __future__ import annotations
import dataclasses
@dataclasses.dataclass
class Node:
h: float = 0.0
g: float = 0.0
f: float = 0.0
opened: int = 0
closed: bool = False
parent: Node = None
retain_count: int = 0
tested: bool = False
def __post_init__(self):
# values used in the finder
self.cleanup()
def __lt__(self, other):
"""
nodes are sorted by f value (see a_star.py)
:param other: compare Node
:return:
"""
return self.f < other.f
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
@dataclasses.dataclass
class GraphNode(Node):
"""
simple node in a graph that's not a grid.
"""
# id of the node in the graph (probably str or int but can be anything)
node_id = object
def __init__(self, node_id):
self.node_id = node_id
self.__post_init__()
def __eq__(self, o):
if isinstance(o, (int, str)):
return o == self.node_id
return self.node_id == o.node_id
def __repr__(self):
return f'<GraphNode({self.node_id} {hex(id(self))})>'
@dataclasses.dataclass
class GridNode(Node):
"""
basic node, saves X and Y coordinates on some grid and determine if
it is walkable.
"""
# Coordinates
x: int = 0
y: int = 0
# Wether this node can be walked through.
walkable: bool = True
# used for weighted algorithms
weight: float = 0.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: int = None
connections: list = None
def __iter__(self):
yield self.x
yield self.y
if self.grid_id is not None:
yield self.grid_id
def connect(self, other_node):
"""
Connect two nodes with each other.
"""
if not self.connections:
self.connections = [other_node]
else:
self.connections.append(other_node)
def __repr__(self):
return f'<GridNode({self.x}:{self.y} {hex(id(self))})>'