Added Recursive Division
This commit is contained in:
parent
2b505bf9a9
commit
514d4577c9
12
main.py
12
main.py
|
@ -7,6 +7,7 @@ pygame.init()
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
# CELL_SIZE = 10
|
# CELL_SIZE = 10
|
||||||
|
# CLOCK_TICK = 20
|
||||||
HIGHLIGHT_COLOR = (0, 0, 255) # Blue for highlighted cells
|
HIGHLIGHT_COLOR = (0, 0, 255) # Blue for highlighted cells
|
||||||
WALL_COLOR = (0, 0, 0) # Black for walls
|
WALL_COLOR = (0, 0, 0) # Black for walls
|
||||||
PATH_COLOR = (255, 255, 255) # White for paths
|
PATH_COLOR = (255, 255, 255) # White for paths
|
||||||
|
@ -59,13 +60,15 @@ class MazeVisualizer:
|
||||||
# Draw the maze regardless of generation state
|
# Draw the maze regardless of generation state
|
||||||
self.draw_maze()
|
self.draw_maze()
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
clock.tick(50) # Adjust speed as needed
|
clock.tick(CLOCK_TICK) # Adjust speed as needed
|
||||||
|
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
CELL_SIZE = 20
|
CELL_SIZE = 10
|
||||||
MAZE_SIZE = 31
|
CLOCK_TICK = 20
|
||||||
|
|
||||||
|
MAZE_SIZE = 63
|
||||||
VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
|
VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
|
||||||
|
|
||||||
# my_maze = maze.RecursiveBacktracker(MAZE_SIZE)
|
# my_maze = maze.RecursiveBacktracker(MAZE_SIZE)
|
||||||
|
@ -75,8 +78,9 @@ VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
|
||||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Down | maze.VectorEnum.Left))
|
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Down | maze.VectorEnum.Left))
|
||||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Down | maze.VectorEnum.Right))
|
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Down | maze.VectorEnum.Right))
|
||||||
# my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.2)
|
# my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.2)
|
||||||
my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.5)
|
# my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.5)
|
||||||
# my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.8)
|
# my_maze = maze.Sidewinder(MAZE_SIZE, run_param=0.8)
|
||||||
|
my_maze = maze.RecursiveDivision(MAZE_SIZE)
|
||||||
|
|
||||||
# for _ in range(512): my_maze.step()
|
# for _ in range(512): my_maze.step()
|
||||||
# for _ in range(2048): my_maze.step()
|
# for _ in range(2048): my_maze.step()
|
||||||
|
|
138
maze.py
138
maze.py
|
@ -493,17 +493,131 @@ class Sidewinder(Maze):
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
|
||||||
neighbors: list[tuple[int,int]] = []
|
|
||||||
x, y = index
|
|
||||||
|
|
||||||
# if x - 2 >= 0:
|
class _Window:
|
||||||
# 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
|
__maze: "RecursiveDivision"
|
||||||
|
__x_start: int
|
||||||
|
__x_stop: int
|
||||||
|
__y_start: int
|
||||||
|
__y_stop: int
|
||||||
|
|
||||||
|
def __init__(self, maze: "RecursiveDivision", x_start: int, x_stop: int, y_start: int, y_stop: int):
|
||||||
|
self.__maze = maze
|
||||||
|
self.__x_start = x_start
|
||||||
|
self.__x_stop = x_stop
|
||||||
|
self.__y_start = y_start
|
||||||
|
self.__y_stop = y_stop
|
||||||
|
|
||||||
|
@property
|
||||||
|
def width(self) -> int:
|
||||||
|
return self.__x_stop - self.__x_start
|
||||||
|
|
||||||
|
@property
|
||||||
|
def height(self) -> int:
|
||||||
|
return self.__y_stop - self.__y_start
|
||||||
|
|
||||||
|
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||||
|
return self.__maze[index[1] - self.__x_start, index[0] - self.__y_start]
|
||||||
|
|
||||||
|
def x(self, x: int) -> int: return x + self.__x_start
|
||||||
|
def y(self, y: int) -> int: return y + self.__y_start
|
||||||
|
|
||||||
|
# def rand_x(self) -> int:
|
||||||
|
# return (random.randint(0, (self.width - 3) // 2) * 2) + 1
|
||||||
|
|
||||||
|
# def rand_y(self) -> int:
|
||||||
|
# return (random.randint(0, (self.height - 3) // 2) * 2) + 1
|
||||||
|
|
||||||
|
def vertical_bisect(self, x: int) -> "tuple[_Window, _Window]":
|
||||||
|
return _Window(
|
||||||
|
self.__maze,
|
||||||
|
self.__x_start,
|
||||||
|
self.__x_start + x,
|
||||||
|
self.__y_start,
|
||||||
|
self.__y_stop,
|
||||||
|
), _Window(
|
||||||
|
self.__maze,
|
||||||
|
self.__x_start + x + 1,
|
||||||
|
self.__x_stop,
|
||||||
|
self.__y_start,
|
||||||
|
self.__y_stop,
|
||||||
|
)
|
||||||
|
|
||||||
|
def horizontal_bisect(self, y: int) -> "tuple[_Window, _Window]":
|
||||||
|
return _Window(
|
||||||
|
self.__maze,
|
||||||
|
self.__x_start,
|
||||||
|
self.__x_stop,
|
||||||
|
self.__y_start,
|
||||||
|
self.__y_start + y,
|
||||||
|
), _Window(
|
||||||
|
self.__maze,
|
||||||
|
self.__x_start,
|
||||||
|
self.__x_stop,
|
||||||
|
self.__y_start + y + 1,
|
||||||
|
self.__y_stop,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RecursiveDivision(Maze):
|
||||||
|
|
||||||
|
__cells: list[list[bool]]
|
||||||
|
# __stack: list[tuple[bool | None, _Window]]
|
||||||
|
__stack: list[tuple[bool, _Window]]
|
||||||
|
__split: tuple[bool, int, _Window] | None
|
||||||
|
|
||||||
|
__width: int
|
||||||
|
__height: int
|
||||||
|
|
||||||
|
def __init__(self, width: int, height: int | None = None):
|
||||||
|
self.__width = width
|
||||||
|
self.__height = height or width
|
||||||
|
self.__cells = [
|
||||||
|
list([(0 < x < self.width-1 and 0 < y < self.height-1)
|
||||||
|
for x in range(self.width)]) for y in range(self.height)]
|
||||||
|
self.__stack = [(True, _Window(self,1,self.width,1,self.height))]
|
||||||
|
self.__split = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def width(self) -> int:
|
||||||
|
return self.__width
|
||||||
|
|
||||||
|
@property
|
||||||
|
def height(self) -> int:
|
||||||
|
return self.__height
|
||||||
|
|
||||||
|
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||||
|
return self.__cells[index[1]][index[0]]
|
||||||
|
|
||||||
|
def step(self) -> bool:
|
||||||
|
if self.__split is not None:
|
||||||
|
if self.__split[0]:
|
||||||
|
axis, y, window = self.__split
|
||||||
|
x = (random.randint(0, (window.width - 3) // 2) * 2)
|
||||||
|
self.__cells[window.y(y)][window.x(x)] = True
|
||||||
|
a, b = [(not axis, w) for w in window.horizontal_bisect(y)]
|
||||||
|
else:
|
||||||
|
axis, x, window = self.__split
|
||||||
|
y = (random.randint(0, (window.height - 3) // 2) * 2)
|
||||||
|
self.__cells[window.y(y)][window.x(x)] = True
|
||||||
|
a, b = [(not axis, w) for w in window.vertical_bisect(x)]
|
||||||
|
if a[1].width > 2 and a[1].height > 2: self.__stack.append(a)
|
||||||
|
if b[1].width > 2 and b[1].height > 2: self.__stack.append(b)
|
||||||
|
self.__split = None
|
||||||
|
return True
|
||||||
|
elif self.__stack:
|
||||||
|
axis, window = self.__stack.pop()
|
||||||
|
# if axis is None: axis = bool(random.randint(0,1))
|
||||||
|
if axis:
|
||||||
|
y = (random.randint(0, (window.height - 3) // 2) * 2) + 1
|
||||||
|
for x in range(window.width):
|
||||||
|
self.__cells[window.y(y)][window.x(x)] = False
|
||||||
|
self.__split = axis, y, window
|
||||||
|
else:
|
||||||
|
x = (random.randint(0, (window.width - 3) // 2) * 2) + 1
|
||||||
|
for y in range(window.height):
|
||||||
|
self.__cells[window.y(y)][window.x(x)] = False
|
||||||
|
self.__split = axis, x, window
|
||||||
|
return True
|
||||||
|
else: return False
|
||||||
|
|
Loading…
Reference in New Issue