Restructuring
This commit is contained in:
parent
e41b857206
commit
bb74cc58e5
10
main.py
10
main.py
|
@ -37,7 +37,7 @@ class MazeVisualizer:
|
|||
def run(self):
|
||||
clock = pygame.time.Clock()
|
||||
running = True
|
||||
generation_complete = False
|
||||
generation_complete = True
|
||||
|
||||
while running:
|
||||
for event in pygame.event.get():
|
||||
|
@ -53,15 +53,15 @@ class MazeVisualizer:
|
|||
# Draw the maze regardless of generation state
|
||||
self.draw_maze()
|
||||
pygame.display.flip()
|
||||
clock.tick(10) # Adjust speed as needed
|
||||
clock.tick(50) # Adjust speed as needed
|
||||
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
# my_maze = maze.RecursiveBacktracker(63)
|
||||
my_maze = maze.OriginShift(63)
|
||||
my_maze = maze.RecursiveBacktracker(63)
|
||||
# my_maze = maze.VectorWrapper(maze.OriginShift(32))
|
||||
# for _ in range(512): my_maze.step()
|
||||
# for _ in range(2048): my_maze.step()
|
||||
for _ in range(16384): my_maze.step()
|
||||
# for _ in range(16384): my_maze.step()
|
||||
visualizer = MazeVisualizer(my_maze)
|
||||
visualizer.run()
|
||||
|
|
199
maze.py
199
maze.py
|
@ -36,6 +36,102 @@ class Maze(abc.ABC):
|
|||
def __list__(self) -> list[list[bool]]:
|
||||
return [list([self[x,y] for x in range(self.width)]) for y in range(self.height)]
|
||||
|
||||
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||
neighbors: list[tuple[int,int]] = []
|
||||
x, y = index
|
||||
|
||||
if x - 2 >= 0:
|
||||
neighbors.append((x - 2,y))
|
||||
if x + 2 < self.width:
|
||||
neighbors.append((x + 2,y))
|
||||
if y - 2 >= 0:
|
||||
neighbors.append((x,y - 2))
|
||||
if y + 2 < self.height:
|
||||
neighbors.append((x,y + 2))
|
||||
|
||||
return neighbors
|
||||
|
||||
|
||||
class VectorEnum(enum.Enum):
|
||||
Zero = 0
|
||||
Up = 1
|
||||
Left = 2
|
||||
Down = 3
|
||||
Right = 4
|
||||
|
||||
|
||||
class VectorMaze(Maze):
|
||||
|
||||
@abc.abstractmethod
|
||||
def __getitem__(self, index: tuple[int,int]) -> VectorEnum:
|
||||
pass
|
||||
|
||||
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||
neighbors: list[tuple[int,int]] = []
|
||||
x, y = index
|
||||
|
||||
if x - 1 >= 0:
|
||||
neighbors.append((x - 1,y))
|
||||
if x + 1 < self.width:
|
||||
neighbors.append((x + 1,y))
|
||||
if y - 1 >= 0:
|
||||
neighbors.append((x,y - 1))
|
||||
if y + 1 < self.height:
|
||||
neighbors.append((x,y + 1))
|
||||
|
||||
return neighbors
|
||||
|
||||
|
||||
class VectorWrapper(Maze):
|
||||
|
||||
__maze: VectorMaze
|
||||
|
||||
def __init__(self, maze: VectorMaze):
|
||||
self.__maze = maze
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
return self.__from_vec(self.__maze.width)
|
||||
|
||||
@property
|
||||
def height(self) -> int:
|
||||
return self.__from_vec(self.__maze.height)
|
||||
|
||||
@property
|
||||
def highlighted(self) -> tuple[int,int] | None:
|
||||
if self.__maze.highlighted is not None:
|
||||
return self.__from_vec(self.__maze.highlighted[0]), self.__from_vec(self.__maze.highlighted[1])
|
||||
else: return None
|
||||
|
||||
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||
x, y = index
|
||||
if x % 2 and y % 2: return True
|
||||
elif x % 2:
|
||||
if self.__to_vec(y-1) >= 0:
|
||||
if self.__maze[self.__to_vec(x), self.__to_vec(y-1)] == VectorEnum.Down:
|
||||
return True
|
||||
if self.__to_vec(y+1) < self.__maze.height:
|
||||
if self.__maze[self.__to_vec(x), self.__to_vec(y+1)] == VectorEnum.Up:
|
||||
return True
|
||||
elif y % 2:
|
||||
if self.__to_vec(x-1) >= 0:
|
||||
if self.__maze[self.__to_vec(x-1), self.__to_vec(y)] == VectorEnum.Right:
|
||||
return True
|
||||
if self.__to_vec(x+1) < self.__maze.width:
|
||||
if self.__maze[self.__to_vec(x+1), self.__to_vec(y)] == VectorEnum.Left:
|
||||
return True
|
||||
return False
|
||||
|
||||
def step(self) -> bool: return self.__maze.step()
|
||||
|
||||
@staticmethod
|
||||
def __from_vec(i: int) -> int:
|
||||
return ((i * 2) + 1)
|
||||
|
||||
@staticmethod
|
||||
def __to_vec(i: int) -> int:
|
||||
return ((i - 1) // 2)
|
||||
|
||||
|
||||
class RecursiveBacktracker(Maze):
|
||||
|
||||
|
@ -66,8 +162,8 @@ class RecursiveBacktracker(Maze):
|
|||
|
||||
@property
|
||||
def highlighted(self) -> tuple[int,int] | None:
|
||||
if self.__stack:
|
||||
return self.__stack[-1]
|
||||
if self.__stack: return self.__stack[-1]
|
||||
else: return None
|
||||
|
||||
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||
return self.__cells[index[1]][index[0]]
|
||||
|
@ -87,30 +183,10 @@ class RecursiveBacktracker(Maze):
|
|||
else: return False
|
||||
|
||||
def __unvisited_neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||
neighbors: list[tuple[int,int]] = []
|
||||
x, y = index
|
||||
|
||||
if x - 2 > 0 and not self[(x - 2,y)]:
|
||||
neighbors.append((x - 2,y))
|
||||
if x + 2 < self.width - 1 and not self[(x + 2,y)]:
|
||||
neighbors.append((x + 2,y))
|
||||
if y - 2 > 0 and not self[(x,y - 2)]:
|
||||
neighbors.append((x,y - 2))
|
||||
if y + 2 < self.height - 1 and not self[(x,y + 2)]:
|
||||
neighbors.append((x,y + 2))
|
||||
|
||||
return neighbors
|
||||
return [(x,y) for x,y in self._neighbors(index) if not self[x,y]]
|
||||
|
||||
|
||||
class VectorEnum(enum.Enum):
|
||||
Zero = 0
|
||||
Up = 1
|
||||
Left = 2
|
||||
Down = 3
|
||||
Right = 4
|
||||
|
||||
|
||||
class OriginShift(Maze):
|
||||
class OriginShift(VectorMaze):
|
||||
|
||||
__cells: list[list[VectorEnum]]
|
||||
|
||||
|
@ -121,7 +197,7 @@ class OriginShift(Maze):
|
|||
self.__width = width
|
||||
self.__height = height or width
|
||||
|
||||
self.__cells = [list([self.__start(x,y) for x in range(self.vec_width)]) for y in range(self.vec_height)]
|
||||
self.__cells = [list([self.__start(x,y) for x in range(self.width)]) for y in range(self.height)]
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
|
@ -136,65 +212,23 @@ class OriginShift(Maze):
|
|||
for y, row in enumerate(self.__cells):
|
||||
for x, cell in enumerate(row):
|
||||
if cell == VectorEnum.Zero:
|
||||
return (self.__from_vec(x), self.__from_vec(y))
|
||||
return (x, y)
|
||||
|
||||
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||
def __getitem__(self, index: tuple[int,int]) -> VectorEnum:
|
||||
x, y = index
|
||||
# print(index)
|
||||
# print(f"Loc: {((x - 1) / 2)}, {((y - 1) / 2)} - {self.__to_vec(x)}, {self.__to_vec(y)}")
|
||||
if x % 2 and y % 2: return True
|
||||
elif x % 2:
|
||||
# print(f"Down: {self.__to_vec(x)}, {self.__to_vec(y-1)}")
|
||||
if self.__to_vec(y-1) >= 0:
|
||||
# print(f"Down: {self.__cells[self.__to_vec(y-1)][self.__to_vec(x)]}")
|
||||
if self.__cells[self.__to_vec(y-1)][self.__to_vec(x)] == VectorEnum.Down:
|
||||
return True
|
||||
# print(f"Up: {self.__to_vec(x)}, {self.__to_vec(y+1)}")
|
||||
if self.__to_vec(y+1) < self.vec_height:
|
||||
# print(f"Up: {self.__cells[self.__to_vec(y+1)][self.__to_vec(x)]}")
|
||||
if self.__cells[self.__to_vec(y+1)][self.__to_vec(x)] == VectorEnum.Up:
|
||||
return True
|
||||
elif y % 2:
|
||||
# print(f"Left: {self.__to_vec(x-1)}, {self.__to_vec(y)}")
|
||||
if self.__to_vec(x-1) >= 0:
|
||||
# print(f"Left: {self.__cells[self.__to_vec(y)][self.__to_vec(x-1)]}")
|
||||
if self.__cells[self.__to_vec(y)][self.__to_vec(x-1)] == VectorEnum.Right:
|
||||
return True
|
||||
# print(f"Right: {self.__to_vec(x+1)}, {self.__to_vec(y)}")
|
||||
if self.__to_vec(x+1) < self.vec_width:
|
||||
# print(f"Right: {self.__cells[self.__to_vec(y)][self.__to_vec(x+1)]}")
|
||||
if self.__cells[self.__to_vec(y)][self.__to_vec(x+1)] == VectorEnum.Left:
|
||||
return True
|
||||
return False
|
||||
return self.__cells[y][x]
|
||||
|
||||
def step(self) -> bool:
|
||||
# return True
|
||||
if self.highlighted is not None:
|
||||
x, y = self.__to_vec(self.highlighted[0]), self.__to_vec(self.highlighted[1])
|
||||
neighbors = self.__neighbors((x,y))
|
||||
x, y = self.highlighted
|
||||
neighbors = self._neighbors((x,y))
|
||||
if neighbors:
|
||||
cell = neighbors[random.randint(0,len(neighbors)-1)]
|
||||
# print((x,y))
|
||||
self.__cells[y][x] = self.__direction((x,y), cell)
|
||||
self.__cells[cell[1]][cell[0]] = VectorEnum.Zero
|
||||
return True
|
||||
else: return False
|
||||
|
||||
def __neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||
neighbors: list[tuple[int,int]] = []
|
||||
x, y = index
|
||||
|
||||
if x - 1 >= 0:
|
||||
neighbors.append((x - 1,y))
|
||||
if x + 1 < self.vec_width:
|
||||
neighbors.append((x + 1,y))
|
||||
if y - 1 >= 0:
|
||||
neighbors.append((x,y - 1))
|
||||
if y + 1 < self.vec_height:
|
||||
neighbors.append((x,y + 1))
|
||||
|
||||
return neighbors
|
||||
|
||||
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
|
||||
if start[0] - end[0] > 0: return VectorEnum.Left
|
||||
if start[0] - end[0] < 0: return VectorEnum.Right
|
||||
|
@ -203,23 +237,6 @@ class OriginShift(Maze):
|
|||
return VectorEnum.Zero
|
||||
|
||||
def __start(self, x: int, y: int) -> VectorEnum:
|
||||
# if x == 0 and y == 0: return VectorEnum.Zero
|
||||
# elif x == 0: return VectorEnum.Up
|
||||
# else: return VectorEnum.Left
|
||||
if x == self.vec_width - 1 and y == self.vec_height - 1: return VectorEnum.Zero
|
||||
elif x == self.vec_width - 1: return VectorEnum.Down
|
||||
if x == self.width - 1 and y == self.height - 1: return VectorEnum.Zero
|
||||
elif x == self.width - 1: return VectorEnum.Down
|
||||
else: return VectorEnum.Right
|
||||
|
||||
def __from_vec(self, i: int) -> int:
|
||||
return ((i * 2) + 1)
|
||||
|
||||
def __to_vec(self, i: int) -> int:
|
||||
return ((i - 1) // 2)
|
||||
|
||||
@property
|
||||
def vec_width(self) -> int:
|
||||
return self.__to_vec(self.width)
|
||||
|
||||
@property
|
||||
def vec_height(self) -> int:
|
||||
return self.__to_vec(self.height)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
+ Origin Shift
|
||||
- Binary Tree
|
||||
- Sidewinder
|
||||
- Binary Division
|
||||
- Recursive Division
|
||||
- Binary Division
|
||||
- Prim's Algorithm
|
||||
- Aldous-Broder Algorithm
|
||||
- Wilson's Algorithm
|
||||
|
|
Loading…
Reference in New Issue