]> Untitled Git - axy/ft/a-maze-ing.git/commitdiff
Pathfinding optimizations
authorAxy <gilliardmarthey.axel@gmail.com>
Wed, 11 Mar 2026 03:49:24 +0000 (04:49 +0100)
committerAxy <gilliardmarthey.axel@gmail.com>
Wed, 11 Mar 2026 03:49:24 +0000 (04:49 +0100)
__main__.py
amazeing/maze_class/maze.py
amazeing/maze_class/maze_walls.py
example.conf

index 0a8ab19648b60c906a89d445a526a8026733b268..77a64936143ae6426e52d808f4ae33a89d2e4f4e 100644 (file)
@@ -109,27 +109,67 @@ def poll_events(timeout_ms: int = -1) -> None:
         backend.present()
 
 
-prev_path: list[IVec2] = []
+prev_solution: list[Cardinal] = []
+
+
+def manhattan_distance(a: IVec2, b: IVec2) -> int:
+    return sum(map(abs, (a - b).xy()))
+
+
+def elipse_manhattan(a: IVec2, b: IVec2, a2: IVec2, b2: IVec2) -> int:
+    return min(
+        manhattan_distance(a1, a2) + manhattan_distance(b1, b2)
+        for a1, b1 in ((a, b), (b, a))
+    )
+
+
+def pathfind_necessary() -> bool:
+    entry = config.entry
+    exit = config.exit
+    if entry is None or exit is None:
+        return False
+    if len(prev_solution) == 0:
+        return True
+    if any(
+        map(
+            lambda e: e in maze.walls_dirty() and maze.get_wall(e).is_full(),
+            Cardinal.path_to_walls(prev_solution, CellCoord(entry)),
+        )
+    ):
+        return True
+    if any(
+        map(
+            lambda e: elipse_manhattan(entry, exit, *e.neighbour_cells())
+            < len(prev_solution),
+            filter(
+                lambda wall: not maze.get_wall(wall).is_full(),
+                maze.walls_dirty(),
+            ),
+        )
+    ):
+        return True
+    return False
 
 
 def pathfind() -> None:
+    if not pathfind_necessary():
+        return
     if config.entry is None or config.exit is None:
         return
     solution = maze.pathfind(CellCoord(config.entry), CellCoord(config.exit))
-    if solution is None:
+    if solution is None or prev_solution == solution:
         return
+    prev_tiles = Cardinal.path_to_tiles(prev_solution, CellCoord(config.entry))
     tiles = Cardinal.path_to_tiles(solution, CellCoord(config.entry))
-    if prev_path == tiles:
-        return
     backend.set_style(empty.curr_style())
-    for tile in prev_path:
+    for tile in prev_tiles:
         backend.draw_tile(tile)
-    prev_path.clear()
-    prev_path.extend(tiles)
     backend.set_style(path.curr_style())
     for tile in tiles:
         backend.draw_tile(tile)
     backend.present()
+    prev_solution.clear()
+    prev_solution.extend(solution)
 
 
 maze_make_perfect(maze, callback=display_maze)
index 1d303b3108aa0725cae3439bf84fc8e2702f56e8..58cfd927959f0d9dd4bbcca3b79c0153f6cbcbc7 100644 (file)
@@ -143,7 +143,7 @@ class Maze:
     def walls_full(self) -> Iterable[WallCoord]:
         return filter(lambda w: self.get_wall(w).is_full(), self.all_walls())
 
-    def walls_dirty(self) -> Iterable[WallCoord]:
+    def walls_dirty(self) -> set[WallCoord]:
         return self.__dirty
 
     def walls_empty(self) -> Iterable[WallCoord]:
index 9baf9a964f4ee2eca4d29c32c80be2cb3ce2f801..3507a8c90a19853686b44e1553d296fec239c2bb 100644 (file)
@@ -1,3 +1,4 @@
+from collections.abc import Generator
 from enum import Enum, auto
 from typing import Iterable, Optional, cast, overload
 from ..maze_display import IVec2
@@ -90,6 +91,25 @@ class Cardinal(Enum):
             src = nxt
         return res
 
+    @staticmethod
+    def path_to_cells(
+        path: list["Cardinal"], src: "CellCoord"
+    ) -> list["CellCoord"]:
+        res = [src]
+        for card in path:
+            src = src.get_neighbour(card)
+            res.append(src)
+        return res
+
+    @staticmethod
+    def path_to_walls(
+        path: list["Cardinal"], src: "CellCoord"
+    ) -> list["WallCoord"]:
+        return [
+            cell.get_wall(card)
+            for cell, card in zip(Cardinal.path_to_cells(path, src), path)
+        ]
+
 
 class WallCoord:
     def __init__(self, orientation: Orientation, a: int, b: int) -> None:
index fbec71b677ae8ef1d1ce2a2e9742e2a120c2a58b..0e0590841c0d7685142c31c6422434a53d1fb76d 100644 (file)
@@ -1,7 +1,7 @@
-WIDTH=40
-HEIGHT=40
-ENTRY=5,5
-EXIT=25,25
+WIDTH=100
+HEIGHT=100
+ENTRY=0,0
+EXIT=99,99
 OUTPUT_FILE=test
 PERFECT=False
 SEED=111
@@ -38,9 +38,9 @@ TILEMAP_BACKGROUND=1"{100,1000,1000:0,0,0}##  ##  "
 #MAZE_PATTERN="#  #  #"
 #MAZE_PATTERN=" ## ## "
 MAZE_PATTERN="  ###  "
-MAZE_PATTERN=" # # # "
+MAZE_PATTERN=" ## ## "
+MAZE_PATTERN="#  #  #"
 MAZE_PATTERN="#  #  #"
-MAZE_PATTERN="#     #"
 MAZE_PATTERN="##   # "
 MAZE_PATTERN="#  #  #"
 MAZE_PATTERN=" #   # "