]> Untitled Git - axy/ft/a-maze-ing.git/commitdiff
Plugging things in
authorAxy <gilliardmarthey.axel@gmail.com>
Fri, 27 Mar 2026 12:08:38 +0000 (13:08 +0100)
committerAxy <gilliardmarthey.axel@gmail.com>
Fri, 27 Mar 2026 12:08:38 +0000 (13:08 +0100)
__main__.py
amazeing/config/config_parser.py
amazeing/display/observer.py
amazeing/maze/make_empty.py
amazeing/maze/make_perfect.py
example.conf

index 2ca0d66dca75267bf8141bc2dd88aa25496070cc..bc8828dc095c83d29114097ef1be0f801ac1d9d5 100644 (file)
@@ -1,4 +1,4 @@
-from amazeing.display.observer import TTYTracker
+from amazeing.display.observer import MazeRegenerate, TTYTracker
 from amazeing.maze import (
     Maze,
     Pattern,
@@ -7,6 +7,7 @@ from amazeing.maze import (
     PacmanTracker,
     make_pacman,
     make_perfect,
+    make_empty,
 )
 from amazeing.config.config_parser import Config
 import random
@@ -20,27 +21,41 @@ maze = Maze(config)
 
 pacman_tracker = PacmanTracker(maze)
 network_tracker = NetworkTracker(maze)
-tty_tracker = TTYTracker(maze, config)
+tty_tracker = TTYTracker(maze, config) if config.visual else None
 
 excluded = {maze.entry, maze.exit}
 
 pattern = Pattern(config.maze_pattern).centered_for(maze.dims, excluded)
-pattern.fill(maze)
-maze.outline()
 
-walls_const = set(maze.walls_full())
 
-make_perfect(maze, network_tracker)
-make_pacman(maze, walls_const, pacman_tracker)
+def maze_main() -> None:
+    pattern.fill(maze)
+    maze.outline()
 
+    walls_const = set(maze.walls_full())
 
-while False:
     make_perfect(maze, network_tracker)
-    make_pacman(maze, walls_const, pacman_tracker)
-    make_empty(maze, walls_const)
-
-
-while True:
-    tty_tracker.display_maze(wait_for_tick=True)
-
-tty_tracker.backend.uninit()
+    if not config.perfect:
+        make_pacman(maze, walls_const, pacman_tracker)
+
+    while config.screensaver:
+        make_perfect(maze, network_tracker)
+        make_pacman(maze, walls_const, pacman_tracker)
+
+
+if config.visual:
+    while True:
+        try:
+            if tty_tracker is not None:
+                tty_tracker.update = False
+                make_empty(maze, set())
+                tty_tracker.update = True
+
+            maze_main()
+
+            while tty_tracker is not None:
+                tty_tracker.display_maze(wait_for_tick=True)
+        except MazeRegenerate:
+            continue
+else:
+    maze_main()
index cddcc40babc31abc901c3a9b739bc55bc635743c..63f18dd71ec6aaf73cacc9cb9b18f4f714fa22a5 100644 (file)
@@ -389,7 +389,6 @@ class Config:
     seed: int | None
     screensaver: bool
     visual: bool
-    interactive: bool
     tilemap_wall_size: IVec2
     tilemap_cell_size: IVec2
     tilemap_full: list[list[ColoredLine]]
@@ -423,7 +422,6 @@ class Config:
                     "SEED": OptionalField(IntField),
                     "SCREENSAVER": DefaultedField(BoolField, False),
                     "VISUAL": DefaultedField(BoolField, False),
-                    "INTERACTIVE": DefaultedField(BoolField, False),
                     "TILEMAP_WALL_SIZE": DefaultedField(
                         CoordField, IVec2(2, 1)
                     ),
index a412213720529d9a76c954f08daea7e1c02afc21..fe61fbec36314b0b679ed89e1b2e5b6830373730 100644 (file)
@@ -1,72 +1,91 @@
+from sys import stderr
 import time
 from amazeing.config.config_parser import Config
-from amazeing.display.tty import TTYBackend, TileCycle, TileMaps, extract_pairs
+from amazeing.display.tty import TTYBackend, TileCycle
 from amazeing.maze.dirty_tracker import DirtyTracker
 from amazeing.maze.maze import Maze
 from amazeing.maze.path import path_pixels, pathfind_astar
 from amazeing.utils.coords import Cardinal
 
 
+class MazeRegenerate(Exception):
+    pass
+
+
 class TTYTracker:
-    def __init__(self, maze: Maze, config: Config):
-        self.maze = maze
-        self.dirty_tracker = DirtyTracker(maze)
-        self.backend = TTYBackend(config)
-        tilemaps = self.backend.tilemaps
-        self.filler_style = TileCycle(tilemaps.filler, self.backend.set_filler)
-        self.empty_style = TileCycle(
-            tilemaps.empty, self.backend.map_style_cb()
+    def __init__(
+        self,
+        maze: Maze,
+        config: Config,
+    ):
+        self.__maze = maze
+        self.__frametime: float = 0.016
+        self.__dirty_tracker = DirtyTracker(maze)
+        self.__backend = TTYBackend(config)
+        tilemaps = self.__backend.tilemaps
+        self.__filler_style = TileCycle(
+            tilemaps.filler, self.__backend.set_filler
+        )
+        self.__empty_style = TileCycle(
+            tilemaps.empty, self.__backend.map_style_cb()
+        )
+        self.__full_style = TileCycle(
+            tilemaps.full, self.__backend.map_style_cb()
+        )
+        self.__path_style = TileCycle(
+            tilemaps.path, self.__backend.map_style_cb()
         )
-        self.full_style = TileCycle(tilemaps.full, self.backend.map_style_cb())
-        self.path_style = TileCycle(tilemaps.path, self.backend.map_style_cb())
 
-        self.backend.set_bg_init(lambda _: self.empty_style.curr_style())
+        self.__backend.set_bg_init(lambda _: self.__empty_style.curr_style())
 
-        self.tick: float | None = None
-        self.prev_path: list[Cardinal] | None = None
-        self.draw_path: bool = True
+        self.__tick: float | None = None
+        self.__path: list[Cardinal] | None = None
+        self.__draw_path: bool = True
 
         maze.observers.add(lambda _: self.display_maze())
+        self.__paused: bool = False
+
+        self.update: bool = True
 
     def clear_backend(self) -> None:
-        self.backend.set_style(self.empty_style.curr_style())
-        for wall in self.dirty_tracker.curr_dirty():
-            if self.maze.get_wall(wall):
+        self.__backend.set_style(self.__empty_style.curr_style())
+        for wall in self.__dirty_tracker.curr_dirty():
+            if self.__maze.get_wall(wall):
                 continue
             for tile in wall.tile_coords():
-                self.backend.draw_tile(tile)
+                self.__backend.draw_tile(tile)
 
     def path_invalidated(self) -> bool:
-        if self.prev_path is None:
+        if self.__path is None:
             return True
-        src = self.maze.entry
-        for card in self.prev_path:
-            if src.get_wall(card) in self.dirty_tracker.curr_dirty():
+        src = self.__maze.entry
+        for card in self.__path:
+            if src.get_wall(card) in self.__dirty_tracker.curr_dirty():
                 return True
             src = src.get_neighbour(card)
         return False
 
+    def redraw_path(self, style: int) -> None:
+        if self.__path is not None:
+            self.__backend.set_style(style)
+            for tile in path_pixels(self.__maze.entry, self.__path):
+                self.__backend.draw_tile(tile)
+
     def display_path(self) -> None:
         if (
-            all(map(self.maze.get_wall, self.dirty_tracker.curr_dirty()))
+            all(map(self.__maze.get_wall, self.__dirty_tracker.curr_dirty()))
             and not self.path_invalidated()
-            and self.draw_path
+            and self.__draw_path
         ):
             return None
-        path = pathfind_astar(self.maze) if self.draw_path else None
-        if self.prev_path is not None:
-            self.backend.set_style(self.empty_style.curr_style())
-            for tile in path_pixels(self.maze.entry, self.prev_path):
-                self.backend.draw_tile(tile)
-        self.prev_path = path
-        if path is not None:
-            self.backend.set_style(self.path_style.curr_style())
-            for tile in path_pixels(self.maze.entry, path):
-                self.backend.draw_tile(tile)
+        path = pathfind_astar(self.__maze) if self.__draw_path else None
+        self.redraw_path(self.__empty_style.curr_style())
+        self.__path = path
+        self.redraw_path(self.__path_style.curr_style())
 
     def poll_events(self) -> None:
         while True:
-            event = self.backend.event()
+            event = self.__backend.event()
             if isinstance(event, bool):
                 if not event:
                     return
@@ -74,49 +93,63 @@ class TTYTracker:
             if event.sym == "q":
                 exit(0)
             if event.sym == "c":
-                self.filler_style.cycle()
-                self.full_style.cycle()
-                self.path_style.cycle()
-                self.empty_style.cycle()
+                self.__filler_style.cycle()
+                self.__full_style.cycle()
+                self.__path_style.cycle()
+                self.__empty_style.cycle()
             if event.sym == "v":
-                self.filler_style.cycle(-1)
-                self.full_style.cycle(-1)
-                self.path_style.cycle(-1)
-                self.empty_style.cycle(-1)
+                self.__filler_style.cycle(-1)
+                self.__full_style.cycle(-1)
+                self.__path_style.cycle(-1)
+                self.__empty_style.cycle(-1)
             if event.sym == "p":
-                self.draw_path = not self.draw_path
+                self.__draw_path = not self.__draw_path
+            if event.sym == "k":
+                self.__paused = not self.__paused
+                try:
+                    while self.__paused:
+                        self.display_maze(True)
+                finally:
+                    self.__paused = False
+            if event.sym == "r":
+                self.redraw_path(self.__filler_style.curr_style())
+                self.__path = None
+                raise MazeRegenerate
             else:
                 continue
 
-    def display_maze(
-        self, wait_for_tick: bool = False, frametime: float = 0.016
-    ) -> None:
+    def display_maze(self, wait_for_tick: bool = False) -> None:
         now = time.monotonic()
-        if self.tick is not None:
+        if self.__tick is not None:
             if wait_for_tick:
-                time.sleep(max(0.0, frametime - now + self.tick))
-            elif now - self.tick < frametime:
+                time.sleep(max(0.0, self.__frametime - now + self.__tick))
+            elif now - self.__tick < self.__frametime:
                 return
-        self.tick = time.monotonic()
+        self.__tick = time.monotonic()
+
+        if not self.update:
+            self.__backend.present()
+            self.poll_events()
+            return
 
         self.clear_backend()
         self.display_path()
 
         rewrites = {
             wall
-            for wall in self.dirty_tracker.curr_dirty()
-            if self.maze.get_wall(wall)
+            for wall in self.__dirty_tracker.curr_dirty()
+            if self.__maze.get_wall(wall)
         } | {
             e
-            for wall in self.dirty_tracker.curr_dirty()
+            for wall in self.__dirty_tracker.curr_dirty()
             for e in wall.neighbours()
-            if self.maze.check_coord(e) and self.maze.get_wall(e)
+            if self.__maze.check_coord(e) and self.__maze.get_wall(e)
         }
 
-        self.backend.set_style(self.full_style.curr_style())
+        self.__backend.set_style(self.__full_style.curr_style())
         for wall in rewrites:
             for pixel in wall.tile_coords():
-                self.backend.draw_tile(pixel)
-        self.dirty_tracker.clear()
-        self.backend.present()
+                self.__backend.draw_tile(pixel)
+        self.__dirty_tracker.clear()
         self.poll_events()
+        self.__backend.present()
index 8b5bceaec7c13114d0d3e8b8828c39fad4ee6c96..f56d53d61e2463b717ce730d2e68980c706c6f65 100644 (file)
@@ -1,4 +1,3 @@
-from collections.abc import Callable
 from amazeing.maze import Maze
 from amazeing.utils import WallCoord
 import random
@@ -7,10 +6,8 @@ import random
 def make_empty(
     maze: Maze,
     walls_const: set[WallCoord],
-    callback: Callable[[Maze], None] = lambda _: None,
 ) -> None:
     walls = [wall for wall in maze.walls_full() if wall not in walls_const]
     random.shuffle(walls)
     for wall in walls:
         maze.set_wall(wall, False)
-        callback(maze)
index 529ffff79c98fb61979d872e7dcf7a3e2fb12053..eb45b6139839252040ce6af4911153712a4b9585 100644 (file)
@@ -1,4 +1,3 @@
-from typing import Callable
 from amazeing.maze import Maze
 import random
 
index 4310962b67b3e5a05a063f534c9170f5cf47a1ce..d752314c938ea6e3c94751dac075ca7f1d3018a7 100644 (file)
@@ -3,7 +3,9 @@ HEIGHT=100
 ENTRY=0,0
 EXIT=24,24
 OUTPUT_FILE=test
-PERFECT=False
+PERFECT=True
+VISUAL=True
+SCREENSAVER=False
 SEED=111
 
 #TILEMAP_WALL_SIZE=2,1