Added Sidewinder Alg
This commit is contained in:
parent
025f00f6aa
commit
2b505bf9a9
21
main.py
21
main.py
|
@ -6,7 +6,7 @@ import sys
|
|||
pygame.init()
|
||||
|
||||
# Constants
|
||||
CELL_SIZE = 10
|
||||
# CELL_SIZE = 10
|
||||
HIGHLIGHT_COLOR = (0, 0, 255) # Blue for highlighted cells
|
||||
WALL_COLOR = (0, 0, 0) # Black for walls
|
||||
PATH_COLOR = (255, 255, 255) # White for paths
|
||||
|
@ -64,12 +64,19 @@ class MazeVisualizer:
|
|||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
# my_maze = maze.RecursiveBacktracker(63)
|
||||
# my_maze = maze.VectorWrapper(maze.OriginShift(32))
|
||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(32, bias=maze.VectorEnum.Up | maze.VectorEnum.Left))
|
||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(32, bias=maze.VectorEnum.Up | maze.VectorEnum.Right))
|
||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(32, bias=maze.VectorEnum.Down | maze.VectorEnum.Left))
|
||||
my_maze = maze.VectorWrapper(maze.BinaryTree(32, bias=maze.VectorEnum.Down | maze.VectorEnum.Right))
|
||||
CELL_SIZE = 20
|
||||
MAZE_SIZE = 31
|
||||
VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
|
||||
|
||||
# my_maze = maze.RecursiveBacktracker(MAZE_SIZE)
|
||||
# my_maze = maze.VectorWrapper(maze.OriginShift(VEC_MAZE_SIZE))
|
||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Up | maze.VectorEnum.Left))
|
||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Up | maze.VectorEnum.Right))
|
||||
# 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.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.8)
|
||||
|
||||
# for _ in range(512): my_maze.step()
|
||||
# for _ in range(2048): my_maze.step()
|
||||
|
|
158
maze.py
158
maze.py
|
@ -1,5 +1,4 @@
|
|||
import abc, enum, random
|
||||
from types import UnionType
|
||||
|
||||
|
||||
class Maze(abc.ABC):
|
||||
|
@ -351,3 +350,160 @@ class BinaryTree(VectorMaze):
|
|||
neighbors.append((x,y + 1))
|
||||
|
||||
return neighbors
|
||||
|
||||
|
||||
class Sidewinder(Maze):
|
||||
|
||||
__cells: list[list[bool]]
|
||||
__run: list[tuple[int,int]]
|
||||
|
||||
__run_param: float
|
||||
__start: VectorEnum
|
||||
|
||||
__width: int
|
||||
__height: int
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
width: int,
|
||||
height: int | None = None,
|
||||
*,
|
||||
run_param: float = 0.5,
|
||||
start: VectorEnum = VectorEnum.Up,
|
||||
):
|
||||
self.__width = width
|
||||
self.__height = height or width
|
||||
self.__cells = [list([False for _ in range(self.width)]) for _ in range(self.height)]
|
||||
self.__start = start
|
||||
self.__run_param = run_param
|
||||
|
||||
if self.__start == VectorEnum.Up:
|
||||
self.__run = [(1,1)]
|
||||
elif self.__start == VectorEnum.Down:
|
||||
self.__run = [(self.width-2,self.height-2)]
|
||||
elif self.__start == VectorEnum.Right:
|
||||
self.__run = [(self.width-2,self.height-2)]
|
||||
elif self.__start == VectorEnum.Left:
|
||||
self.__run = [(1,1)]
|
||||
else:
|
||||
self.__run = []
|
||||
|
||||
self.__cells[self.highlighted[1]][self.highlighted[0]] = True # type: ignore
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
return self.__width
|
||||
|
||||
@property
|
||||
def height(self) -> int:
|
||||
return self.__height
|
||||
|
||||
@property
|
||||
def highlighted(self) -> tuple[int,int] | None:
|
||||
if self.__run: return self.__run[-1]
|
||||
else: return None
|
||||
|
||||
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||
return self.__cells[index[1]][index[0]]
|
||||
|
||||
def step(self) -> bool:
|
||||
if self.highlighted is not None:
|
||||
hx, hy = self.highlighted
|
||||
|
||||
if hx - 2 >= 0 and self.__start == VectorEnum.Down:
|
||||
cell = (hx - 2, hy)
|
||||
carve = hy + 2 >= self.height or random.random() > self.__run_param
|
||||
elif hx + 2 < self.width and self.__start == VectorEnum.Up:
|
||||
cell = (hx + 2, hy)
|
||||
carve = hy - 2 < 0 or random.random() > self.__run_param
|
||||
elif hy - 2 >= 0 and self.__start == VectorEnum.Right:
|
||||
cell = (hx, hy - 2)
|
||||
carve = hx + 2 >= self.width or random.random() > self.__run_param
|
||||
elif hy + 2 < self.height and self.__start == VectorEnum.Left:
|
||||
cell = (hx, hy + 2)
|
||||
carve = hx - 2 < 0 or random.random() > self.__run_param
|
||||
else:
|
||||
cell = None
|
||||
carve = False
|
||||
|
||||
if cell is not None and carve:
|
||||
x = (hx + cell[0]) // 2
|
||||
y = (hy + cell[1]) // 2
|
||||
self.__cells[y][x] = True
|
||||
self.__cells[cell[1]][cell[0]] = True
|
||||
self.__run.append(cell)
|
||||
else:
|
||||
hx, hy = self.highlighted
|
||||
sx, sy = self.__run[random.randint(0,len(self.__run)-1)]
|
||||
self.__run.clear()
|
||||
|
||||
if self.__start == VectorEnum.Down:
|
||||
if hx - 2 >= 0:
|
||||
x, y = (hx - 2, hy)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
else:
|
||||
if hy - 2 >= 0:
|
||||
x, y = (self.width - 2, hy - 2)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
if sy + 2 < self.height: cell = (sx, sy + 2)
|
||||
else: cell = None
|
||||
elif self.__start == VectorEnum.Up:
|
||||
if hx + 2 < self.width:
|
||||
x, y = (hx + 2, hy)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
else:
|
||||
if hy + 2 < self.height:
|
||||
x, y = (1, hy + 2)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
if sy - 2 >= 0: cell = (sx, sy - 2)
|
||||
else: cell = None
|
||||
elif self.__start == VectorEnum.Right:
|
||||
if hy - 2 >= 0:
|
||||
x, y = (hx, hy - 2)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
else:
|
||||
if hx - 2 >= 0:
|
||||
x, y = (hx - 2, self.height - 2)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
if sx + 2 < self.height: cell = (sx + 2, sy)
|
||||
else: cell = None
|
||||
elif self.__start == VectorEnum.Left:
|
||||
if hy + 2 < self.height:
|
||||
x, y = (hx, hy + 2)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
else:
|
||||
if hx + 2 < self.width:
|
||||
x, y = (hx + 2, 1)
|
||||
self.__run.append((x,y))
|
||||
self.__cells[y][x] = True
|
||||
if sx - 2 >= 0: cell = (sx - 2, sy)
|
||||
else: cell = None
|
||||
|
||||
if cell is not None:
|
||||
x = (sx + cell[0]) // 2
|
||||
y = (sy + cell[1]) // 2
|
||||
self.__cells[y][x] = True
|
||||
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 - 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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
+ Recursive Backtracking
|
||||
+ Origin Shift
|
||||
+ Binary Tree
|
||||
- Sidewinder
|
||||
+ Sidewinder
|
||||
- Recursive Division
|
||||
- Binary Division
|
||||
- Prim's Algorithm
|
||||
|
|
Loading…
Reference in New Issue