make_pacman(maze, walls_const, pacman_tracker)
-while True:
+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()
+ tty_tracker.display_maze(wait_for_tick=True)
tty_tracker.backend.uninit()
),
"TILEMAP_FULL": DefaultedStrField(
ColoredLineField,
- ['"{WHITE:WHITE} "', '"{WHITE:WHITE} "'],
+ [
+ '1"{WHITE:WHITE} "',
+ '1"{WHITE:WHITE} "',
+ '2"{MAGENTA:MAGENTA} "',
+ '2"{MAGENTA:MAGENTA} "',
+ ],
),
"TILEMAP_EMPTY": DefaultedStrField(
ColoredLineField,
),
"TILEMAP_PATH": DefaultedStrField(
ColoredLineField,
- ['"{BLUE:BLUE} "', '"{BLUE:BLUE} "'],
+ [
+ '1"{BLUE:BLUE} "',
+ '1"{BLUE:BLUE} "',
+ '2"{RED:RED} "',
+ '2"{RED:RED} "',
+ ],
),
"TILEMAP_BACKGROUND_SIZE": DefaultedField(
CoordField, IVec2(4, 2)
self.tick: float | None = None
self.prev_path: list[Cardinal] | None = None
+ self.draw_path: bool = True
maze.observers.add(lambda _: self.display_maze())
if (
all(map(self.maze.get_wall, self.dirty_tracker.curr_dirty()))
and not self.path_invalidated()
+ and self.draw_path
):
return None
- path = pathfind_astar(self.maze)
+ path = pathfind_astar(self.maze) if self.draw_path else None
if self.prev_path is not None:
- if self.prev_path == path:
- return
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)
def poll_events(self) -> None:
while True:
- event = self.backend.event(0)
+ event = self.backend.event()
if isinstance(event, bool):
if not event:
return
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
else:
continue
- def display_maze(self) -> None:
+ def display_maze(
+ self, wait_for_tick: bool = False, frametime: float = 0.016
+ ) -> None:
now = time.monotonic()
- if self.tick is not None and now - self.tick < 0.016:
- return
+ if self.tick is not None:
+ if wait_for_tick:
+ time.sleep(max(0.0, frametime - now + self.tick))
+ elif now - self.tick < frametime:
+ return
self.tick = time.monotonic()
self.clear_backend()
self.__uninit: bool = False
self.__screen: curses.window = curses.initscr()
+ self.__screen.timeout(0)
curses.start_color()
curses.noecho()
curses.cbreak()
],
)
- self.__resize: bool = False
+ self.__redraw: bool = True
self.__filler: None | int = None
def set_filler(self, style: int) -> None:
if self.__filler == style:
return
+ self.__redraw = True
self.__filler = style
for box in self.__filler_boxes:
box.mark_dirty()
if src == dst:
return
if self.get_style_height(src) != 0:
+ self.__redraw = True
self.__drawn = QuadTree()
self.__style_bimap.key_map(src, dst)
style = self.__style
self.__style_bimap.add(style, pos)
self.__tilemap.draw_at(pos, style, self.__pad.pad)
+ self.__redraw = True
def set_style(self, style: int) -> None:
self.__style = style
def present(self) -> None:
- if self.__resize:
- self.__resize = False
- self.__screen.erase()
- for box in self.__filler_boxes:
- box.mark_dirty()
+ if not self.__redraw:
+ return
+ self.__redraw = False
self.__screen.refresh()
y, x = self.__screen.getmaxyx()
self.__scratch.resize(y, x)
self.__layout.laid_out(IVec2(0, 0), IVec2(x, y))
self.__scratch.overwrite(self.__screen)
- def event(self, timeout_ms: int = -1) -> KeyboardInput | bool:
- self.__screen.timeout(timeout_ms)
+ def event(self) -> KeyboardInput | bool:
try:
key = self.__screen.getkey()
except curses.error:
match key:
case "KEY_RESIZE":
- self.__resize = True
+ self.__screen.erase()
+ for box in self.__filler_boxes:
+ box.mark_dirty()
case "KEY_DOWN":
self.__pad.scroll(IVec2(0, 1))
case "KEY_UP":
self.__pad.scroll(IVec2(-1, 0))
case _:
return KeyboardInput(key)
+ self.__redraw = True
return True
-WIDTH=16
-HEIGHT=16
+WIDTH=100
+HEIGHT=100
ENTRY=0,0
EXIT=24,24
OUTPUT_FILE=test