Reversed maze cell boolean values and clean up
This commit is contained in:
parent
f79b8bdb3e
commit
e583199976
10
game.py
10
game.py
|
@ -65,7 +65,7 @@ def draw_map(
|
||||||
|
|
||||||
for y in range(world_map.height):
|
for y in range(world_map.height):
|
||||||
for x in range(world_map.width):
|
for x in range(world_map.width):
|
||||||
if not world_map[x, y]:
|
if world_map[x, y]:
|
||||||
pygame.draw.rect(screen, pygame.Color(255,255,255), pygame.Rect(
|
pygame.draw.rect(screen, pygame.Color(255,255,255), pygame.Rect(
|
||||||
(pygame.Vector2(x, y)) +
|
(pygame.Vector2(x, y)) +
|
||||||
(pygame.Vector2(screen.size) // 2), (1, 1)))
|
(pygame.Vector2(screen.size) // 2), (1, 1)))
|
||||||
|
@ -96,7 +96,8 @@ def draw_game(
|
||||||
|
|
||||||
pygame.draw.line(
|
pygame.draw.line(
|
||||||
screen,
|
screen,
|
||||||
pygame.Color(192,192,192) if side else pygame.Color(255,255,255),
|
pygame.Color(192,192,192) if side else
|
||||||
|
pygame.Color(255,255,255),
|
||||||
(x, draw_start),
|
(x, draw_start),
|
||||||
(x, draw_end),
|
(x, draw_end),
|
||||||
)
|
)
|
||||||
|
@ -108,7 +109,8 @@ def ray(
|
||||||
max_dis_squared: int = 10_000,
|
max_dis_squared: int = 10_000,
|
||||||
debug: bool = False
|
debug: bool = False
|
||||||
) -> tuple[float, int | None]:
|
) -> tuple[float, int | None]:
|
||||||
delta = pygame.Vector2(1/max(abs(ray_dir.x),1e-3),1/max(abs(ray_dir.y),1e-3))
|
delta = pygame.Vector2(
|
||||||
|
1/max(abs(ray_dir.x),1e-3),1/max(abs(ray_dir.y),1e-3))
|
||||||
map_pos = pygame.Vector2(int(ray_pos.x),int(ray_pos.y))
|
map_pos = pygame.Vector2(int(ray_pos.x),int(ray_pos.y))
|
||||||
step = pygame.Vector2(0,0)
|
step = pygame.Vector2(0,0)
|
||||||
side_dis = pygame.Vector2(0,0)
|
side_dis = pygame.Vector2(0,0)
|
||||||
|
@ -145,7 +147,7 @@ def ray(
|
||||||
map_pos.y >= 0 and
|
map_pos.y >= 0 and
|
||||||
map_pos.x < world_map.width and
|
map_pos.x < world_map.width and
|
||||||
map_pos.y < world_map.height and
|
map_pos.y < world_map.height and
|
||||||
world_map[int(map_pos.x),int(map_pos.y)]
|
not world_map[int(map_pos.x),int(map_pos.y)]
|
||||||
): break
|
): break
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
191
maze.py
191
maze.py
|
@ -31,7 +31,7 @@ class Maze(abc.ABC):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def secondary(self, index: tuple[int,int]) -> bool:
|
def secondary(self, index: tuple[int,int]) -> bool:
|
||||||
return False
|
return True
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
s = ""
|
s = ""
|
||||||
|
@ -42,7 +42,8 @@ class Maze(abc.ABC):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def __list__(self) -> list[list[bool]]:
|
def __list__(self) -> list[list[bool]]:
|
||||||
return [list([self[x,y] for x in range(self.width)]) for y in range(self.height)]
|
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]]:
|
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||||
neighbors: list[tuple[int,int]] = []
|
neighbors: list[tuple[int,int]] = []
|
||||||
|
@ -95,7 +96,8 @@ class VectorMaze(Maze):
|
||||||
return VectorEnum.Null
|
return VectorEnum.Null
|
||||||
|
|
||||||
def __list__(self) -> list[list[VectorEnum]]:
|
def __list__(self) -> list[list[VectorEnum]]:
|
||||||
return [list([self[x,y] for x in range(self.width)]) for y in range(self.height)]
|
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]]:
|
def _neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
||||||
neighbors: list[tuple[int,int]] = []
|
neighbors: list[tuple[int,int]] = []
|
||||||
|
@ -131,7 +133,10 @@ class VectorWrapper(Maze):
|
||||||
@property
|
@property
|
||||||
def highlighted(self) -> tuple[int,int] | None:
|
def highlighted(self) -> tuple[int,int] | None:
|
||||||
if self.__maze.highlighted is not None:
|
if self.__maze.highlighted is not None:
|
||||||
return self.__from_vec(self.__maze.highlighted[0]), self.__from_vec(self.__maze.highlighted[1])
|
return (
|
||||||
|
self.__from_vec(self.__maze.highlighted[0]),
|
||||||
|
self.__from_vec(self.__maze.highlighted[1])
|
||||||
|
)
|
||||||
else: return None
|
else: return None
|
||||||
|
|
||||||
def __getitem__(self, index: tuple[int,int]) -> bool:
|
def __getitem__(self, index: tuple[int,int]) -> bool:
|
||||||
|
@ -144,22 +149,26 @@ class VectorWrapper(Maze):
|
||||||
x, y = index
|
x, y = index
|
||||||
if x % 2 and y % 2:
|
if x % 2 and y % 2:
|
||||||
if key((self.__to_vec(x), self.__to_vec(y))) != VectorEnum.Null:
|
if key((self.__to_vec(x), self.__to_vec(y))) != VectorEnum.Null:
|
||||||
return True
|
return False
|
||||||
elif x % 2:
|
elif x % 2:
|
||||||
if self.__to_vec(y-1) >= 0:
|
if self.__to_vec(y-1) >= 0:
|
||||||
if key((self.__to_vec(x), self.__to_vec(y-1))) == VectorEnum.Down:
|
if key((self.__to_vec(x), self.__to_vec(y-1))) == \
|
||||||
return True
|
VectorEnum.Down:
|
||||||
|
return False
|
||||||
if self.__to_vec(y+1) < self.__maze.height:
|
if self.__to_vec(y+1) < self.__maze.height:
|
||||||
if key((self.__to_vec(x), self.__to_vec(y+1))) == VectorEnum.Up:
|
if key((self.__to_vec(x), self.__to_vec(y+1))) == \
|
||||||
return True
|
VectorEnum.Up:
|
||||||
|
return False
|
||||||
elif y % 2:
|
elif y % 2:
|
||||||
if self.__to_vec(x-1) >= 0:
|
if self.__to_vec(x-1) >= 0:
|
||||||
if key((self.__to_vec(x-1), self.__to_vec(y))) == VectorEnum.Right:
|
if key((self.__to_vec(x-1), self.__to_vec(y))) == \
|
||||||
return True
|
VectorEnum.Right:
|
||||||
if self.__to_vec(x+1) < self.__maze.width:
|
|
||||||
if key((self.__to_vec(x+1), self.__to_vec(y))) == VectorEnum.Left:
|
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
if self.__to_vec(x+1) < self.__maze.width:
|
||||||
|
if key((self.__to_vec(x+1), self.__to_vec(y))) == \
|
||||||
|
VectorEnum.Left:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def step(self) -> bool: return self.__maze.step()
|
def step(self) -> bool: return self.__maze.step()
|
||||||
|
|
||||||
|
@ -217,13 +226,14 @@ class RecursiveBacktracker(Maze):
|
||||||
def __init__(self, width: int, height: int | None = None):
|
def __init__(self, width: int, height: int | None = None):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
self.__cells = [list([False for _ in range(self.width)]) for _ in range(self.height)]
|
self.__cells = [
|
||||||
|
list([True for _ in range(self.width)]) for _ in range(self.height)]
|
||||||
self.__stack = [(
|
self.__stack = [(
|
||||||
(random.randint(0, ((self.width - 1) // 2) - 1) * 2) + 1,
|
(random.randint(0, ((self.width - 1) // 2) - 1) * 2) + 1,
|
||||||
(random.randint(0, ((self.height - 1) // 2) - 1) * 2) + 1
|
(random.randint(0, ((self.height - 1) // 2) - 1) * 2) + 1
|
||||||
)]
|
)]
|
||||||
|
|
||||||
self.__cells[self.highlighted[1]][self.highlighted[0]] = True # type: ignore
|
self.__cells[self.__stack[-1][1]][self.__stack[-1][0]] = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self) -> int:
|
def width(self) -> int:
|
||||||
|
@ -248,15 +258,18 @@ class RecursiveBacktracker(Maze):
|
||||||
cell = neighbors[random.randint(0,len(neighbors)-1)]
|
cell = neighbors[random.randint(0,len(neighbors)-1)]
|
||||||
x = (self.highlighted[0] + cell[0]) // 2
|
x = (self.highlighted[0] + cell[0]) // 2
|
||||||
y = (self.highlighted[1] + cell[1]) // 2
|
y = (self.highlighted[1] + cell[1]) // 2
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
self.__cells[cell[1]][cell[0]] = True
|
self.__cells[cell[1]][cell[0]] = False
|
||||||
self.__stack.append(cell)
|
self.__stack.append(cell)
|
||||||
else: self.__stack.pop()
|
else: self.__stack.pop()
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
def __unvisited_neighbors(self, index: tuple[int,int]) -> list[tuple[int,int]]:
|
def __unvisited_neighbors(
|
||||||
return [(x,y) for x,y in self._neighbors(index) if not self[x,y]]
|
self,
|
||||||
|
index: tuple[int,int],
|
||||||
|
) -> list[tuple[int,int]]:
|
||||||
|
return [(x,y) for x,y in self._neighbors(index) if self[x,y]]
|
||||||
|
|
||||||
|
|
||||||
class OriginShift(VectorMaze):
|
class OriginShift(VectorMaze):
|
||||||
|
@ -270,7 +283,9 @@ class OriginShift(VectorMaze):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
|
|
||||||
self.__cells = [list([self.__start(x,y) for x in range(self.width)]) for y in range(self.height)]
|
self.__cells = [
|
||||||
|
list([self.__start(x,y) for x in range(self.width)])
|
||||||
|
for y in range(self.height)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self) -> int:
|
def width(self) -> int:
|
||||||
|
@ -306,13 +321,21 @@ class OriginShift(VectorMaze):
|
||||||
def clone(cls, other: VectorMaze | list[list[VectorEnum]]) -> "OriginShift":
|
def clone(cls, other: VectorMaze | list[list[VectorEnum]]) -> "OriginShift":
|
||||||
if isinstance(other, VectorMaze):
|
if isinstance(other, VectorMaze):
|
||||||
self = cls(other.width, other.height)
|
self = cls(other.width, other.height)
|
||||||
self.__cells = [list([other[x,y] for x in range(other.width)]) for y in range(other.height)]
|
self.__cells = [
|
||||||
|
list([other[x,y] for x in range(other.width)])
|
||||||
|
for y in range(other.height)]
|
||||||
else:
|
else:
|
||||||
self = cls(len(other[0]), len(other))
|
self = cls(len(other[0]), len(other))
|
||||||
self.__cells = [list([other[y][x] for x in range(len(other[0]))]) for y in range(len(other))]
|
self.__cells = [
|
||||||
|
list([other[y][x] for x in range(len(other[0]))])
|
||||||
|
for y in range(len(other))]
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
|
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.Left
|
||||||
if start[0] - end[0] < 0: return VectorEnum.Right
|
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.Up
|
||||||
|
@ -337,7 +360,12 @@ class BinaryTree(VectorMaze):
|
||||||
__x: int
|
__x: int
|
||||||
__y: int
|
__y: int
|
||||||
|
|
||||||
def __init__(self, width: int, height: int | None = None, *, bias: int | None = None ):
|
def __init__(
|
||||||
|
self,
|
||||||
|
width: int,
|
||||||
|
height: int | None = None,
|
||||||
|
*, bias: int | None = None,
|
||||||
|
):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
|
|
||||||
|
@ -346,7 +374,9 @@ class BinaryTree(VectorMaze):
|
||||||
self.__x = 0
|
self.__x = 0
|
||||||
self.__y = 0
|
self.__y = 0
|
||||||
|
|
||||||
self.__cells = [list([VectorEnum.Null for x in range(self.width)]) for y in range(self.height)]
|
self.__cells = [
|
||||||
|
list([VectorEnum.Null for _ in range(self.width)])
|
||||||
|
for _ in range(self.height)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self) -> int:
|
def width(self) -> int:
|
||||||
|
@ -370,7 +400,8 @@ class BinaryTree(VectorMaze):
|
||||||
neighbors = self._neighbors(self.highlighted)
|
neighbors = self._neighbors(self.highlighted)
|
||||||
if neighbors:
|
if neighbors:
|
||||||
cell = neighbors[random.randint(0,len(neighbors)-1)]
|
cell = neighbors[random.randint(0,len(neighbors)-1)]
|
||||||
self.__cells[self.__y][self.__x] = self.__direction(self.highlighted, cell)
|
self.__cells[self.__y][self.__x] = self.__direction(
|
||||||
|
self.highlighted, cell)
|
||||||
else:
|
else:
|
||||||
self.__cells[self.__y][self.__x] = VectorEnum.Zero
|
self.__cells[self.__y][self.__x] = VectorEnum.Zero
|
||||||
self.__x += 1
|
self.__x += 1
|
||||||
|
@ -380,7 +411,11 @@ class BinaryTree(VectorMaze):
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
|
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.Left
|
||||||
if start[0] < end[0]: return VectorEnum.Right
|
if start[0] < end[0]: return VectorEnum.Right
|
||||||
if start[1] > end[1]: return VectorEnum.Up
|
if start[1] > end[1]: return VectorEnum.Up
|
||||||
|
@ -393,11 +428,13 @@ class BinaryTree(VectorMaze):
|
||||||
|
|
||||||
if x - 1 >= 0 and (self.__bias & VectorEnum.Left) == VectorEnum.Left:
|
if x - 1 >= 0 and (self.__bias & VectorEnum.Left) == VectorEnum.Left:
|
||||||
neighbors.append((x - 1,y))
|
neighbors.append((x - 1,y))
|
||||||
if x + 1 < self.width and (self.__bias & VectorEnum.Right) == VectorEnum.Right:
|
if x + 1 < self.width and (self.__bias & VectorEnum.Right) == \
|
||||||
|
VectorEnum.Right:
|
||||||
neighbors.append((x + 1,y))
|
neighbors.append((x + 1,y))
|
||||||
if y - 1 >= 0 and (self.__bias & VectorEnum.Up) == VectorEnum.Up:
|
if y - 1 >= 0 and (self.__bias & VectorEnum.Up) == VectorEnum.Up:
|
||||||
neighbors.append((x,y - 1))
|
neighbors.append((x,y - 1))
|
||||||
if y + 1 < self.height and (self.__bias & VectorEnum.Down) == VectorEnum.Down:
|
if y + 1 < self.height and (self.__bias & VectorEnum.Down) == \
|
||||||
|
VectorEnum.Down:
|
||||||
neighbors.append((x,y + 1))
|
neighbors.append((x,y + 1))
|
||||||
|
|
||||||
return neighbors
|
return neighbors
|
||||||
|
@ -424,7 +461,8 @@ class Sidewinder(Maze):
|
||||||
):
|
):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
self.__cells = [list([False for _ in range(self.width)]) for _ in range(self.height)]
|
self.__cells = [
|
||||||
|
list([True for _ in range(self.width)]) for _ in range(self.height)]
|
||||||
self.__start = start
|
self.__start = start
|
||||||
self.__run_param = run_param
|
self.__run_param = run_param
|
||||||
|
|
||||||
|
@ -439,7 +477,7 @@ class Sidewinder(Maze):
|
||||||
else:
|
else:
|
||||||
self.__run = []
|
self.__run = []
|
||||||
|
|
||||||
self.__cells[self.highlighted[1]][self.highlighted[0]] = True # type: ignore
|
self.__cells[self.__run[-1][1]][self.__run[-1][0]] = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self) -> int:
|
def width(self) -> int:
|
||||||
|
@ -463,13 +501,15 @@ class Sidewinder(Maze):
|
||||||
|
|
||||||
if hx - 2 >= 0 and self.__start == VectorEnum.Down:
|
if hx - 2 >= 0 and self.__start == VectorEnum.Down:
|
||||||
cell = (hx - 2, hy)
|
cell = (hx - 2, hy)
|
||||||
carve = hy + 2 >= self.height or random.random() > self.__run_param
|
carve = (
|
||||||
|
hy + 2 >= self.height or random.random() > self.__run_param)
|
||||||
elif hx + 2 < self.width and self.__start == VectorEnum.Up:
|
elif hx + 2 < self.width and self.__start == VectorEnum.Up:
|
||||||
cell = (hx + 2, hy)
|
cell = (hx + 2, hy)
|
||||||
carve = hy - 2 < 0 or random.random() > self.__run_param
|
carve = hy - 2 < 0 or random.random() > self.__run_param
|
||||||
elif hy - 2 >= 0 and self.__start == VectorEnum.Right:
|
elif hy - 2 >= 0 and self.__start == VectorEnum.Right:
|
||||||
cell = (hx, hy - 2)
|
cell = (hx, hy - 2)
|
||||||
carve = hx + 2 >= self.width or random.random() > self.__run_param
|
carve = (
|
||||||
|
hx + 2 >= self.width or random.random() > self.__run_param)
|
||||||
elif hy + 2 < self.height and self.__start == VectorEnum.Left:
|
elif hy + 2 < self.height and self.__start == VectorEnum.Left:
|
||||||
cell = (hx, hy + 2)
|
cell = (hx, hy + 2)
|
||||||
carve = hx - 2 < 0 or random.random() > self.__run_param
|
carve = hx - 2 < 0 or random.random() > self.__run_param
|
||||||
|
@ -480,8 +520,8 @@ class Sidewinder(Maze):
|
||||||
if cell is not None and carve:
|
if cell is not None and carve:
|
||||||
x = (hx + cell[0]) // 2
|
x = (hx + cell[0]) // 2
|
||||||
y = (hy + cell[1]) // 2
|
y = (hy + cell[1]) // 2
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
self.__cells[cell[1]][cell[0]] = True
|
self.__cells[cell[1]][cell[0]] = False
|
||||||
self.__run.append(cell)
|
self.__run.append(cell)
|
||||||
else:
|
else:
|
||||||
hx, hy = self.highlighted
|
hx, hy = self.highlighted
|
||||||
|
@ -492,55 +532,55 @@ class Sidewinder(Maze):
|
||||||
if hx - 2 >= 0:
|
if hx - 2 >= 0:
|
||||||
x, y = (hx - 2, hy)
|
x, y = (hx - 2, hy)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
else:
|
else:
|
||||||
if hy - 2 >= 0:
|
if hy - 2 >= 0:
|
||||||
x, y = (self.width - 2, hy - 2)
|
x, y = (self.width - 2, hy - 2)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
if sy + 2 < self.height: cell = (sx, sy + 2)
|
if sy + 2 < self.height: cell = (sx, sy + 2)
|
||||||
else: cell = None
|
else: cell = None
|
||||||
elif self.__start == VectorEnum.Up:
|
elif self.__start == VectorEnum.Up:
|
||||||
if hx + 2 < self.width:
|
if hx + 2 < self.width:
|
||||||
x, y = (hx + 2, hy)
|
x, y = (hx + 2, hy)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
else:
|
else:
|
||||||
if hy + 2 < self.height:
|
if hy + 2 < self.height:
|
||||||
x, y = (1, hy + 2)
|
x, y = (1, hy + 2)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
if sy - 2 >= 0: cell = (sx, sy - 2)
|
if sy - 2 >= 0: cell = (sx, sy - 2)
|
||||||
else: cell = None
|
else: cell = None
|
||||||
elif self.__start == VectorEnum.Right:
|
elif self.__start == VectorEnum.Right:
|
||||||
if hy - 2 >= 0:
|
if hy - 2 >= 0:
|
||||||
x, y = (hx, hy - 2)
|
x, y = (hx, hy - 2)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
else:
|
else:
|
||||||
if hx - 2 >= 0:
|
if hx - 2 >= 0:
|
||||||
x, y = (hx - 2, self.height - 2)
|
x, y = (hx - 2, self.height - 2)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
if sx + 2 < self.height: cell = (sx + 2, sy)
|
if sx + 2 < self.height: cell = (sx + 2, sy)
|
||||||
else: cell = None
|
else: cell = None
|
||||||
elif self.__start == VectorEnum.Left:
|
elif self.__start == VectorEnum.Left:
|
||||||
if hy + 2 < self.height:
|
if hy + 2 < self.height:
|
||||||
x, y = (hx, hy + 2)
|
x, y = (hx, hy + 2)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
else:
|
else:
|
||||||
if hx + 2 < self.width:
|
if hx + 2 < self.width:
|
||||||
x, y = (hx + 2, 1)
|
x, y = (hx + 2, 1)
|
||||||
self.__run.append((x,y))
|
self.__run.append((x,y))
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
if sx - 2 >= 0: cell = (sx - 2, sy)
|
if sx - 2 >= 0: cell = (sx - 2, sy)
|
||||||
else: cell = None
|
else: cell = None
|
||||||
|
|
||||||
if cell is not None:
|
if cell is not None:
|
||||||
x = (sx + cell[0]) // 2
|
x = (sx + cell[0]) // 2
|
||||||
y = (sy + cell[1]) // 2
|
y = (sy + cell[1]) // 2
|
||||||
self.__cells[y][x] = True
|
self.__cells[y][x] = False
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
|
@ -553,7 +593,14 @@ class _Window:
|
||||||
__y_start: int
|
__y_start: int
|
||||||
__y_stop: int
|
__y_stop: int
|
||||||
|
|
||||||
def __init__(self, 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.__maze = maze
|
||||||
self.__x_start = x_start
|
self.__x_start = x_start
|
||||||
self.__x_stop = x_stop
|
self.__x_stop = x_stop
|
||||||
|
@ -633,7 +680,7 @@ class RecursiveDivision(Maze):
|
||||||
self.__uniform = uniform
|
self.__uniform = uniform
|
||||||
self.__depth_first = depth_first
|
self.__depth_first = depth_first
|
||||||
self.__cells = [
|
self.__cells = [
|
||||||
list([(0 < x < self.width-1 and 0 < y < self.height-1)
|
list([(not (0 < x < self.width-1 and 0 < y < self.height-1))
|
||||||
for x in range(self.width)]) for y in range(self.height)]
|
for x in range(self.width)]) for y in range(self.height)]
|
||||||
self.__stack = [
|
self.__stack = [
|
||||||
((True if self.__uniform else None),
|
((True if self.__uniform else None),
|
||||||
|
@ -656,14 +703,14 @@ class RecursiveDivision(Maze):
|
||||||
if self.__split[0]:
|
if self.__split[0]:
|
||||||
axis, y, window = self.__split
|
axis, y, window = self.__split
|
||||||
x = (random.randint(0, (window.width - 1) // 2) * 2)
|
x = (random.randint(0, (window.width - 1) // 2) * 2)
|
||||||
self.__cells[window.y(y)][window.x(x)] = True
|
self.__cells[window.y(y)][window.x(x)] = False
|
||||||
a, b = [
|
a, b = [
|
||||||
((not axis if self.__uniform else None), w)
|
((not axis if self.__uniform else None), w)
|
||||||
for w in window.horizontal_bisect(y)]
|
for w in window.horizontal_bisect(y)]
|
||||||
else:
|
else:
|
||||||
axis, x, window = self.__split
|
axis, x, window = self.__split
|
||||||
y = (random.randint(0, (window.height - 1) // 2) * 2)
|
y = (random.randint(0, (window.height - 1) // 2) * 2)
|
||||||
self.__cells[window.y(y)][window.x(x)] = True
|
self.__cells[window.y(y)][window.x(x)] = False
|
||||||
a, b = [
|
a, b = [
|
||||||
((not axis if self.__uniform else None), w)
|
((not axis if self.__uniform else None), w)
|
||||||
for w in window.vertical_bisect(x)]
|
for w in window.vertical_bisect(x)]
|
||||||
|
@ -678,13 +725,13 @@ class RecursiveDivision(Maze):
|
||||||
if self.__binary: y = (((window.height - 3) // 4) * 2) + 1
|
if self.__binary: y = (((window.height - 3) // 4) * 2) + 1
|
||||||
else: y = (random.randint(0, (window.height - 3) // 2) * 2) + 1
|
else: y = (random.randint(0, (window.height - 3) // 2) * 2) + 1
|
||||||
for x in range(window.width):
|
for x in range(window.width):
|
||||||
self.__cells[window.y(y)][window.x(x)] = False
|
self.__cells[window.y(y)][window.x(x)] = True
|
||||||
self.__split = axis, y, window
|
self.__split = axis, y, window
|
||||||
else:
|
else:
|
||||||
if self.__binary: x = (((window.width - 3) // 4) * 2) + 1
|
if self.__binary: x = (((window.width - 3) // 4) * 2) + 1
|
||||||
else: x = (random.randint(0, (window.width - 3) // 2) * 2) + 1
|
else: x = (random.randint(0, (window.width - 3) // 2) * 2) + 1
|
||||||
for y in range(window.height):
|
for y in range(window.height):
|
||||||
self.__cells[window.y(y)][window.x(x)] = False
|
self.__cells[window.y(y)][window.x(x)] = True
|
||||||
self.__split = axis, x, window
|
self.__split = axis, x, window
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
@ -699,11 +746,13 @@ class Prim(VectorMaze):
|
||||||
|
|
||||||
__frontier: set[tuple[int,int]]
|
__frontier: set[tuple[int,int]]
|
||||||
|
|
||||||
def __init__(self, width: int, height: int | None = None, *, bias: int | None = None ):
|
def __init__(self, width: int, height: int | None = None):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
|
|
||||||
self.__cells = [list([VectorEnum.Null for _ in range(self.width)]) for _ in range(self.height)]
|
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)
|
x, y = random.randint(0,self.width-1), random.randint(0,self.height-1)
|
||||||
|
|
||||||
|
@ -725,25 +774,35 @@ class Prim(VectorMaze):
|
||||||
|
|
||||||
def step(self) -> bool:
|
def step(self) -> bool:
|
||||||
if self.__frontier:
|
if self.__frontier:
|
||||||
cell_a = list(self.__frontier)[random.randint(0,len(self.__frontier)-1)]
|
cell_a = list(
|
||||||
|
self.__frontier)[random.randint(0,len(self.__frontier)-1)]
|
||||||
self.__frontier.remove(cell_a)
|
self.__frontier.remove(cell_a)
|
||||||
neighbors = self._neighbors(cell_a, True)
|
neighbors = self._neighbors(cell_a, True)
|
||||||
cell_b = neighbors.pop(random.randint(0,len(neighbors)-1))
|
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.__cells[cell_a[1]][cell_a[0]] = self.__direction(
|
||||||
|
cell_a, cell_b)
|
||||||
|
|
||||||
self.__frontier.update(self._neighbors(cell_a, False))
|
self.__frontier.update(self._neighbors(cell_a, False))
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
|
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.Left
|
||||||
if start[0] < end[0]: return VectorEnum.Right
|
if start[0] < end[0]: return VectorEnum.Right
|
||||||
if start[1] > end[1]: return VectorEnum.Up
|
if start[1] > end[1]: return VectorEnum.Up
|
||||||
if start[1] < end[1]: return VectorEnum.Down
|
if start[1] < end[1]: return VectorEnum.Down
|
||||||
return VectorEnum.Zero
|
return VectorEnum.Zero
|
||||||
|
|
||||||
def _neighbors(self, index: tuple[int,int], inside=False) -> list[tuple[int,int]]:
|
def _neighbors(
|
||||||
|
self,
|
||||||
|
index: tuple[int,int],
|
||||||
|
inside=False,
|
||||||
|
) -> list[tuple[int,int]]:
|
||||||
neighbors: list[tuple[int,int]] = []
|
neighbors: list[tuple[int,int]] = []
|
||||||
x, y = index
|
x, y = index
|
||||||
|
|
||||||
|
@ -779,11 +838,13 @@ class Wilson(VectorMaze):
|
||||||
__path: dict[tuple[int,int], VectorEnum]
|
__path: dict[tuple[int,int], VectorEnum]
|
||||||
__start: tuple[int,int] | None
|
__start: tuple[int,int] | None
|
||||||
|
|
||||||
def __init__(self, width: int, height: int | None = None, *, bias: int | None = None ):
|
def __init__(self, width: int, height: int | None = None):
|
||||||
self.__width = width
|
self.__width = width
|
||||||
self.__height = height or width
|
self.__height = height or width
|
||||||
|
|
||||||
self.__cells = [list([VectorEnum.Null for _ in range(self.width)]) for _ in range(self.height)]
|
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)
|
x, y = random.randint(0,self.width-1), random.randint(0,self.height-1)
|
||||||
self.__cells[y][x] = VectorEnum.Zero
|
self.__cells[y][x] = VectorEnum.Zero
|
||||||
|
@ -865,14 +926,22 @@ class Wilson(VectorMaze):
|
||||||
if empty: return empty[random.randint(0,len(empty)-1)]
|
if empty: return empty[random.randint(0,len(empty)-1)]
|
||||||
else: return None
|
else: return None
|
||||||
|
|
||||||
def __direction(self, start: tuple[int,int], end: tuple[int,int]) -> VectorEnum:
|
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.Left
|
||||||
if start[0] < end[0]: return VectorEnum.Right
|
if start[0] < end[0]: return VectorEnum.Right
|
||||||
if start[1] > end[1]: return VectorEnum.Up
|
if start[1] > end[1]: return VectorEnum.Up
|
||||||
if start[1] < end[1]: return VectorEnum.Down
|
if start[1] < end[1]: return VectorEnum.Down
|
||||||
return VectorEnum.Zero
|
return VectorEnum.Zero
|
||||||
|
|
||||||
def __next(self, index: tuple[int,int], direction: VectorEnum) -> tuple[int,int]:
|
def __next(
|
||||||
|
self,
|
||||||
|
index: tuple[int,int],
|
||||||
|
direction: VectorEnum,
|
||||||
|
) -> tuple[int,int]:
|
||||||
if direction == VectorEnum.Up: return index[0], index[1]-1
|
if direction == VectorEnum.Up: return index[0], index[1]-1
|
||||||
elif direction == VectorEnum.Down: return index[0], index[1]+1
|
elif direction == VectorEnum.Down: return index[0], index[1]+1
|
||||||
elif direction == VectorEnum.Left: return index[0]-1, index[1]
|
elif direction == VectorEnum.Left: return index[0]-1, index[1]
|
||||||
|
|
50
visualize.py
50
visualize.py
|
@ -19,24 +19,41 @@ class MazeVisualizer:
|
||||||
self.maze = maze
|
self.maze = maze
|
||||||
self.screen_width = maze.width * CELL_SIZE
|
self.screen_width = maze.width * CELL_SIZE
|
||||||
self.screen_height = maze.height * CELL_SIZE
|
self.screen_height = maze.height * CELL_SIZE
|
||||||
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
|
self.screen = pygame.display.set_mode(
|
||||||
|
(self.screen_width, self.screen_height))
|
||||||
pygame.display.set_caption("Maze Generator Visualization")
|
pygame.display.set_caption("Maze Generator Visualization")
|
||||||
|
|
||||||
def draw_maze(self):
|
def draw_maze(self):
|
||||||
self.screen.fill(PATH_COLOR)
|
self.screen.fill(PATH_COLOR)
|
||||||
for y in range(self.maze.height):
|
for y in range(self.maze.height):
|
||||||
for x in range(self.maze.width):
|
for x in range(self.maze.width):
|
||||||
if not self.maze[x, y]:
|
if self.maze[x, y]:
|
||||||
pygame.draw.rect(self.screen, WALL_COLOR,
|
pygame.draw.rect(
|
||||||
pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE))
|
self.screen,
|
||||||
if self.maze.secondary((x, y)):
|
WALL_COLOR,
|
||||||
pygame.draw.rect(self.screen, SECONDARY_COLOR,
|
pygame.Rect(
|
||||||
pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE))
|
x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
|
||||||
|
)
|
||||||
|
if not self.maze.secondary((x, y)):
|
||||||
|
pygame.draw.rect(
|
||||||
|
self.screen,
|
||||||
|
SECONDARY_COLOR,
|
||||||
|
pygame.Rect(
|
||||||
|
x * CELL_SIZE,
|
||||||
|
y * CELL_SIZE,
|
||||||
|
CELL_SIZE,
|
||||||
|
CELL_SIZE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if self.maze.highlighted:
|
if self.maze.highlighted:
|
||||||
hx, hy = self.maze.highlighted
|
hx, hy = self.maze.highlighted
|
||||||
pygame.draw.rect(self.screen, HIGHLIGHT_COLOR,
|
pygame.draw.rect(
|
||||||
pygame.Rect(hx * CELL_SIZE, hy * CELL_SIZE, CELL_SIZE, CELL_SIZE))
|
self.screen,
|
||||||
|
HIGHLIGHT_COLOR,
|
||||||
|
pygame.Rect(
|
||||||
|
hx * CELL_SIZE, hy * CELL_SIZE, CELL_SIZE, CELL_SIZE)
|
||||||
|
)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
clock = pygame.time.Clock()
|
clock = pygame.time.Clock()
|
||||||
|
@ -52,7 +69,8 @@ class MazeVisualizer:
|
||||||
generation_complete = not generation_complete
|
generation_complete = not generation_complete
|
||||||
if event.key == pygame.K_o:
|
if event.key == pygame.K_o:
|
||||||
if isinstance(self.maze, maze.VectorWrapper):
|
if isinstance(self.maze, maze.VectorWrapper):
|
||||||
self.maze = maze.VectorWrapper(maze.OriginShift.clone(self.maze.maze))
|
self.maze = maze.VectorWrapper(
|
||||||
|
maze.OriginShift.clone(self.maze.maze))
|
||||||
if event.key == pygame.K_s:
|
if event.key == pygame.K_s:
|
||||||
if generation_complete: self.maze.step()
|
if generation_complete: self.maze.step()
|
||||||
if event.key == pygame.K_h:
|
if event.key == pygame.K_h:
|
||||||
|
@ -87,10 +105,14 @@ VEC_MAZE_SIZE = (MAZE_SIZE + 1) // 2
|
||||||
|
|
||||||
# my_maze = maze.RecursiveBacktracker(MAZE_SIZE)
|
# my_maze = maze.RecursiveBacktracker(MAZE_SIZE)
|
||||||
# my_maze = maze.VectorWrapper(maze.OriginShift(VEC_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(
|
||||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Up | maze.VectorEnum.Right))
|
# VEC_MAZE_SIZE, bias=maze.VectorEnum.Up | 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(
|
||||||
# my_maze = maze.VectorWrapper(maze.BinaryTree(VEC_MAZE_SIZE, bias=maze.VectorEnum.Down | maze.VectorEnum.Right))
|
# 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.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)
|
||||||
|
|
Loading…
Reference in New Issue