Added Prim's Alg

This commit is contained in:
Kyler Olsen 2024-11-06 22:22:45 -07:00
parent b9ecf665a8
commit 9dc41e9ba8
3 changed files with 86 additions and 6 deletions

View File

@ -94,7 +94,8 @@ VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
# my_maze = maze.RecursiveDivision(MAZE_SIZE)
# my_maze = maze.RecursiveDivision(MAZE_SIZE, uniform=False)
# my_maze = maze.RecursiveDivision(MAZE_SIZE, depth_first=False)
my_maze = maze.RecursiveDivision(MAZE_SIZE, binary=True)
# my_maze = maze.RecursiveDivision(MAZE_SIZE, binary=True)
my_maze = maze.VectorWrapper(maze.Prim(VEC_MAZE_SIZE))
# for _ in range(512): my_maze.step()
# for _ in range(2048): my_maze.step()

87
maze.py
View File

@ -361,10 +361,10 @@ class BinaryTree(VectorMaze):
else: return False
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
if start[1] - end[1] > 0: return VectorEnum.Up
if start[1] - end[1] < 0: return VectorEnum.Down
if start[0] > end[0]: return VectorEnum.Left
if start[0] < end[0]: return VectorEnum.Right
if start[1] > end[1]: return VectorEnum.Up
if start[1] < end[1]: return VectorEnum.Down
return VectorEnum.Zero
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
@ -668,3 +668,82 @@ class RecursiveDivision(Maze):
self.__split = axis, x, window
return True
else: return False
class Prim(VectorMaze):
__cells: list[list[VectorEnum]]
__width: int
__height: int
__frontier: set[tuple[int,int]]
def __init__(self, width: int, height: int | None = None, *, bias: int | None = None ):
self.__width = width
self.__height = height or width
self.__cells = [list([VectorEnum.Null for _ in range(self.width)]) for _ in range(self.height)]
x, y = random.randint(0,self.width-1), random.randint(0,self.height-1)
self.__cells[y][x] = VectorEnum.Zero
self.__frontier = set(self._neighbors((x,y), False))
@property
def width(self) -> int:
return self.__width
@property
def height(self) -> int:
return self.__height
def __getitem__(self, index: tuple[int,int]) -> VectorEnum:
x, y = index
return self.__cells[y][x]
def step(self) -> bool:
if self.__frontier:
cell_a = list(self.__frontier)[random.randint(0,len(self.__frontier)-1)]
self.__frontier.remove(cell_a)
neighbors = self._neighbors(cell_a, True)
cell_b = neighbors.pop(random.randint(0,len(neighbors)-1))
self.__cells[cell_a[1]][cell_a[0]] = self.__direction(cell_a, cell_b)
self.__frontier.update(self._neighbors(cell_a, False))
return True
else: return False
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
if start[0] > end[0]: return VectorEnum.Left
if start[0] < end[0]: return VectorEnum.Right
if start[1] > end[1]: return VectorEnum.Up
if start[1] < end[1]: return VectorEnum.Down
return VectorEnum.Zero
def _neighbors(self, index: tuple[int,int], inside=False) -> list[tuple[int,int]]:
neighbors: list[tuple[int,int]] = []
x, y = index
if inside:
if x - 1 >= 0 and self.__cells[y][x-1] != VectorEnum.Null:
neighbors.append((x - 1,y))
if x + 1 < self.width and self.__cells[y][x+1] != VectorEnum.Null:
neighbors.append((x + 1,y))
if y - 1 >= 0 and self.__cells[y-1][x] != VectorEnum.Null:
neighbors.append((x,y - 1))
if y + 1 < self.height and self.__cells[y+1][x] != VectorEnum.Null:
neighbors.append((x,y + 1))
else:
if x - 1 >= 0 and self.__cells[y][x-1] == VectorEnum.Null:
neighbors.append((x - 1,y))
if x + 1 < self.width and self.__cells[y][x+1] == VectorEnum.Null:
neighbors.append((x + 1,y))
if y - 1 >= 0 and self.__cells[y-1][x] == VectorEnum.Null:
neighbors.append((x,y - 1))
if y + 1 < self.height and self.__cells[y+1][x] == VectorEnum.Null:
neighbors.append((x,y + 1))
return neighbors

View File

@ -4,7 +4,7 @@
+ Sidewinder
+ Recursive Division
+ Binary Division
- Prim's Algorithm
+ Prim's Algorithm
- Aldous-Broder Algorithm
- Wilson's Algorithm
- Aldous-Broder-Wilson Algorithm