maze.outline()
-pattern = Pattern(config.maze_pattern).centered_for(
- dims, {CellCoord(5, 5), CellCoord(10, 10)}
-)
+excluded = set()
+if config.entry is not None:
+ excluded.add(config.entry)
+if config.exit is not None:
+ excluded.add(config.exit)
+
+pattern = Pattern(config.maze_pattern).centered_for(dims, excluded)
pattern.fill(maze)
walls_const = set(maze.walls_full())
continue
for tile in wall.tile_coords():
backend.draw_tile(tile)
- pass
def display_maze(maze: Maze) -> None:
maze.clear_dirty()
backend.present()
poll_events(0)
- # poll_events(0)
def poll_events(timeout_ms: int = -1) -> None:
maze_make_perfect(maze, callback=display_maze)
maze_make_pacman(maze, walls_const, callback=display_maze)
+print(
+ maze.pathfind(CellCoord(config.entry), CellCoord(config.exit)), file=stderr
+)
while False:
maze_make_perfect(maze, callback=display_maze)
# poll_events(200)
return recognize(seq(tag("#"), many_count(none_of("\n"))))(s)
+def parse_empty_line(s: str) -> ParseResult[None]:
+ return (None, s) if s.startswith("\n") else None
+
+
def spaced[T](parser: Parser[T]) -> Parser[T]:
return delimited(multispace0, parser, multispace0)
)
for name, field in fields.items()
),
+ parser_map(lambda _: None, parse_empty_line),
)
+from sys import stderr
from typing import Callable, Generator, Iterable, cast
from amazeing.maze_display.backend import IVec2
from .maze_walls import (
+ Cardinal,
+ CellCoord,
MazeWall,
NetworkID,
Orientation,
def clear_dirty(self) -> None:
self.__dirty = set()
+
+ def pathfind(
+ self, src: CellCoord, dst: CellCoord
+ ) -> list[Cardinal] | None:
+ class Path:
+ def __init__(self, prev: tuple["Path", Cardinal] | None) -> None:
+ self.prev: tuple["Path", Cardinal] | None = prev
+
+ def to_list(self) -> list[Cardinal]:
+ if self.prev is None:
+ return []
+ prev, direction = self.prev
+ prev_list = prev.to_list()
+ prev_list.append(direction)
+ return prev_list
+
+ def __add__(self, value: Cardinal) -> "Path":
+ return Path((self, value))
+
+ walls_empty = set(self.walls_empty())
+ visited = set()
+ border = {src: Path(None)}
+ while len(border) != 0:
+ border_next = {}
+ for pos, path in border.items():
+ if pos == dst:
+ return path.to_list()
+ visited.add(pos)
+ for direction in Cardinal.all():
+ if pos.get_wall(direction) not in walls_empty:
+ continue
+ neighbour = pos.get_neighbour(direction)
+ if neighbour in visited:
+ continue
+ if neighbour in border or neighbour in border_next:
+ continue
+ border_next[neighbour] = path + direction
+ border = border_next
+
+ return None
normalized: Pattern = self.normalized()
negative = normalized.flood_filled().mirrored()
dims = normalized.dims()
- slots = set(CellCoord(canvas - dims + 1).all_up_to())
+ slots = set(
+ map(
+ lambda e: CellCoord(e + 1),
+ CellCoord(canvas - dims - 1).all_up_to(),
+ )
+ )
for excluded in excluding:
slots -= negative.offset(excluded).__cells
if len(slots) == 0:
def right(self) -> "Cardinal":
return self.left().opposite()
+ @staticmethod
+ def all() -> list["Cardinal"]:
+ return [Cardinal.NORTH, Cardinal.SOUTH, Cardinal.EAST, Cardinal.WEST]
+
class WallCoord:
def __init__(self, orientation: Orientation, a: int, b: int) -> None:
return WallCoord(Orientation.HORIZONTAL, self.y, self.x)
case Cardinal.SOUTH:
return WallCoord(Orientation.HORIZONTAL, self.y + 1, self.x)
- case Cardinal.EAST:
- return WallCoord(Orientation.VERTICAL, self.x, self.y)
case Cardinal.WEST:
+ return WallCoord(Orientation.VERTICAL, self.x, self.y)
+ case Cardinal.EAST:
return WallCoord(Orientation.VERTICAL, self.x + 1, self.y)
+ def get_neighbour(self, cardinal: Cardinal) -> "CellCoord":
+ return next(
+ filter(
+ lambda e: e != self, self.get_wall(cardinal).neighbour_cells()
+ )
+ )
+
def tile_coords(self) -> IVec2:
return IVec2(self.x * 2 + 1, self.y * 2 + 1)
yield CellCoord(x, y)
def neighbours_unchecked(self) -> Iterable["CellCoord"]:
- return map(
- self.offset, [IVec2(-1, 0), IVec2(1, 0), IVec2(0, -1), IVec2(0, 1)]
- )
+ return map(self.get_neighbour, Cardinal.all())
WIDTH=20
HEIGHT=20
-ENTRY=2,5
-#EXIT=100,100
+ENTRY=5,5
+EXIT=10,10
OUTPUT_FILE=test
PERFECT=False
SEED=111
TILEMAP_BACKGROUND="{1000,1000,1000:0,0,0}###### "
TILEMAP_BACKGROUND="{1000,1000,1000:0,0,0} ## "
TILEMAP_BACKGROUND="{1000,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="# # #"
MAZE_PATTERN="# #"
-MAZE_PATTERN="## ####"
-MAZE_PATTERN="# #"
+MAZE_PATTERN="## # "
MAZE_PATTERN="# # #"
-MAZE_PATTERN="#######"
+MAZE_PATTERN=" # # "
+MAZE_PATTERN=" ### "