Scattered optimizations for pathfinding

This commit is contained in:
Emi Simpson 2023-02-12 17:23:31 -05:00
parent 66bd8bbec8
commit 5fac1d9c25
Signed by: Emi
GPG Key ID: A12F2C2FFDC3D847
2 changed files with 18 additions and 16 deletions

View File

@ -77,25 +77,23 @@ def pathfind(
(2, 3), (3, 3), (3, 4), (4, 4), (5, 4), (6, 4), (2, 3), (3, 3), (3, 4), (4, 4), (5, 4), (6, 4),
(6, 3), (6, 2), (7, 2), (7, 1), (7, 0)), 19)) (6, 3), (6, 2), (7, 2), (7, 1), (7, 0)), 19))
""" """
@tco_rec frontier, visited = ([_FrontierNode(0, 0, start_state, tuple())], set())
def pathfind_inner( while True:
frontier: List[_FrontierNode[S]],
visited: Set[S]
) -> Return[Option[Tuple[Tuple[S, ...], int]]] | Recur[[List[_FrontierNode[S]], Set[S]]]:
# Don't look at this in mypy # Don't look at this in mypy
# The types check out but mypy is REALLY bad at unifying types # The types check out but mypy is REALLY bad at unifying types
match try_(ident, heappop, frontier): match try_(ident, heappop, frontier):
case Err(_): case Err(_):
return Return(None) return None
case Ok(current) if current.node in visited: case Ok(current) if current.node in visited:
return Recur(frontier, visited) pass #RECUR
case Ok(current): case Ok(current):
new_path = (*current.path, current.node) new_path = (*current.path, current.node)
if goal(current.node): if goal(current.node):
return Return(Some((new_path, current.total_cost))) return Some((new_path, current.total_cost))
else: else:
visited.add(current.node) visited.add(current.node)
return Recur(
frontier, visited = ( #RECUR
_heappush_all( _heappush_all(
frontier, frontier,
[ [
@ -111,7 +109,6 @@ def pathfind(
), ),
visited visited
) )
return pathfind_inner([_FrontierNode(0, 0, start_state, tuple())], set())
@tco_rec @tco_rec
def pathfind_multi( def pathfind_multi(

View File

@ -132,7 +132,7 @@ class World:
""" """
Look up terrain cost and elevation by point Look up terrain cost and elevation by point
""" """
return self.tiles[loc.to_linear(self.width)] return self.tiles[loc.x + self.width * loc.y]
def elevation_difference(self, p1: Point, p2: Point): def elevation_difference(self, p1: Point, p2: Point):
""" """
@ -144,7 +144,7 @@ class World:
>>> world.elevation_difference(Point(0, 0), Point(1, 0)) >>> world.elevation_difference(Point(0, 0), Point(1, 0))
100 100
""" """
return abs(self[p1][1] - self[p2][1]) return self[p2][1] - self[p1][1]
def neighbors(self, loc: Point) -> List[Tuple[Point, int]]: def neighbors(self, loc: Point) -> List[Tuple[Point, int]]:
""" """
@ -255,7 +255,6 @@ class World:
and adj_point.y >= 0 and adj_point.y >= 0
and adj_point.x < self.width and adj_point.x < self.width
and adj_point.y < len(self.tiles) // self.width and adj_point.y < len(self.tiles) // self.width
and self[adj_point][0] != Terrain.OOB
] ]
def heuristic(self, a: Point, b: Point) -> int: def heuristic(self, a: Point, b: Point) -> int:
@ -288,9 +287,15 @@ class World:
lat_tiles_raw = abs(a.y - b.y) lat_tiles_raw = abs(a.y - b.y)
# The number of moves necessary, allowing diagonal moves # The number of moves necessary, allowing diagonal moves
lon_moves_real = max(0, lon_tiles_raw - lat_tiles_raw) vh_moves = lon_tiles_raw - lat_tiles_raw
lat_moves_real = max(0, lat_tiles_raw - lon_tiles_raw) if vh_moves > 0:
diag_moves_real = min(lat_tiles_raw, lon_tiles_raw) lon_moves_real = vh_moves
lat_moves_real = 0
diag_moves_real = lat_tiles_raw
else:
lat_moves_real = -vh_moves
lon_moves_real = 0
diag_moves_real = lon_tiles_raw
# Total distance necessary, not counting elevation # Total distance necessary, not counting elevation
total_flat_distance = ( total_flat_distance = (