'Python Object suddenly went Empty and all attributs are False
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
import random
from abc import abstractmethod
class Cell:
NUMBER_OF_CELLS = 0
def __init__(self):
self.id = Cell.NUMBER_OF_CELLS
Cell.NUMBER_OF_CELLS += 1
self.top_cell = None
self.bottom_cell = None
self.left_cell = None
self.right_cell = None
self.top_wall = True
self.bottom_wall = True
self.left_wall = True
self.right_wall = True
self.visited = False
def set_visited(self, visited: bool) -> None:
"""Sets the visited status of the cell
Args:
visited (bool): The visited status to set
"""
self.visited = visited
def has_unvisited_neighbors(self) -> bool:
"""Check if all neighbors are visited or not
Returns:
bool: True if there is at least one, else False
"""
return (
self.top_cell is not None
and not self.top_cell.visited
or self.bottom_cell is not None
and not self.bottom_cell.visited
or self.left_cell is not None
and not self.left_cell.visited
or self.right_cell is not None
and not self.right_cell.visited
)
def get_unvisited_neighbors(self) -> list["Cell"]:
"""Get all univisited neighbors of the cell (top, bottom, left and right)
Returns:
list["Cell"]: List of unvisited neighbors (cells)
"""
neighbors = []
if self.top_cell is not None and not self.top_cell.visited:
neighbors.append(self.top_cell)
if self.bottom_cell is not None and not self.bottom_cell.visited:
neighbors.append(self.bottom_cell)
if self.left_cell is not None and not self.left_cell.visited:
neighbors.append(self.left_cell)
if self.right_cell is not None and not self.right_cell.visited:
neighbors.append(self.right_cell)
return neighbors
def open_wall_with(self, cell: "Cell") -> None:
"""Opens the wall in the given direction for both cells (method called and parameter one)
Args:
cell (Cell): The cell to open the wall with
"""
direction = self.get_direction(cell)
if direction == "top":
self.top_wall = False
self.top_cell.bottom_wall = False
elif direction == "bottom":
self.bottom_wall = False
self.bottom_cell.top_wall = False
elif direction == "left":
self.left_wall = False
self.left_cell.right_wall = False
elif direction == "right":
self.right_wall = False
self.right_cell.left_wall = False
def get_direction(self, cell: "Cell") -> str:
"""Gets the direction to the given cell from this cell
Args:
cell (Cell): The cell to get the direction to
Returns:
str: The direction to the given cell or empty string if not found
"""
if self.top_cell is cell:
return "top"
elif self.bottom_cell is cell:
return "bottom"
elif self.left_cell is cell:
return "left"
elif self.right_cell is cell:
return "right"
else:
return ""
def __str__(self):
tmp = ""
tmp += "1" if self.top_wall else "0"
tmp += "1" if self.bottom_wall else "0"
tmp += "1" if self.left_wall else "0"
tmp += "1" if self.right_wall else "0"
return f" {tmp} "
class Maze:
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self.cells = [[Cell() for _ in range(height)] for _ in range(width)]
self.link_cells()
def __str__(self):
s = ""
for i in range(self.height):
for j in range(self.width):
s += str(self.cells[j][i])
s += "\n"
return s
def link_cells(self) -> None:
"""Links all cells recursively"""
for i in range(self.width):
for j in range(self.height):
cell = self.cells[i][j]
if j > 0:
cell.top_cell = self.cells[i][j - 1]
if j < self.height - 1:
cell.bottom_cell = self.cells[i][j + 1]
if i > 0:
cell.left_cell = self.cells[i - 1][j]
if i < self.width - 1:
cell.right_cell = self.cells[i + 1][j]
class MazeBuilder:
ALGORITHMS = []
def __init__(self, num: int):
MazeBuilder.ALGORITHMS = [
method_name
for method_name in dir(self)
if callable(getattr(self, method_name)) and not method_name.startswith("__")
and method_name != "build"
]
self.algorithm = MazeBuilder.ALGORITHMS[num]
def build(self, maze: Maze) -> None:
self.algorithm(maze)
@staticmethod
def depth_first_search(maze: Maze) -> None:
"""Depth First Search algorithm (iterative, cuz the recursive one overflows the stack)
Args:
maze (Maze): An untouched maze object to be built upon
"""
maze.cells[0][0].set_visited(True)
stack = [maze.cells[0][0]]
while len(stack) != 0:
current_cell = stack.pop()
if current_cell.has_unvisited_neighbors():
stack.append(current_cell)
chosen_cell = random.choice(current_cell.get_unvisited_neighbors())
current_cell.open_wall_with(chosen_cell)
chosen_cell.set_visited(True)
stack.append(chosen_cell)
class MazeSolver:
ALGORITHMS = []
def __init__(self, num: int):
MazeSolver.ALGORITHMS = [
method_name
for method_name in dir(self)
if callable(getattr(self, method_name)) and not method_name.startswith("__")
and method_name != "solve"
]
self.algorithm = MazeSolver.ALGORITHMS[num]
def solve(self, maze: Maze) -> None:
self.algorithm(maze)
@staticmethod
def a_star(maze: Maze) -> None:
"""Depth First Search algorithm (iterative, cuz the recursive one overflows the stack)
Args:
maze (Maze): An untouched maze object to be built upon
"""
pass
class Color:
WHITE = pygame.Color("white")
BLACK = pygame.Color("black")
RED = pygame.Color("red")
BLUE = pygame.Color("blue")
class Window:
FPS = 60
WIDTH = 1280
HEIGHT = 720
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((Window.WIDTH, Window.HEIGHT))
self.screen.fill(Color.WHITE)
pygame.display.set_caption("MazeBuild&Solve")
self.run = False
self.clock = pygame.time.Clock()
@abstractmethod
def start(self):
raise NotImplementedError("Not implemented abstract method for object type 'Window'")
class MazeDrawer(Window):
def __init__(self, alg_gen: int, alg_sol: int, width: int, height: int):
super().__init__()
self.maze_builder = MazeBuilder(alg_gen)
self.maze_solver = MazeSolver(alg_sol)
self.maze = Maze(width, height)
def _draw_line(self, start_coords: tuple, end_coords: tuple):
pygame.draw.line(self.screen, Color.BLACK, start_coords, end_coords)
def _draw_maze(self) -> None:
"""Draw the maze on pygame's window"""
pass
def start(self):
self.run = True
while self.run:
# Setting the tick to Window.FPS (default: 60)
self.clock.tick(Window.FPS)
# Looking for any event
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.run = False
self._draw_maze()
pygame.display.update()
pygame.display.flip()
def main():
_ = MazeBuilder(0) # Needed to init the MazeBuilder.ALGORITHMS list
_ = MazeSolver(0) # Needed to init the MazeSolver.ALGORITHMS list
alg_gen, alg_sol, width, height = -1, -1, -1, -1
for i in range(len(MazeBuilder.ALGORITHMS)):
print(f"{i}: {MazeBuilder.ALGORITHMS[i]}")
print()
while(alg_gen := int(input("Input the n° of the algorithm for the generation: ")) not in range(len(MazeBuilder.ALGORITHMS))):
continue
print()
for i in range(len(MazeSolver.ALGORITHMS)):
print(f"{i}: {MazeSolver.ALGORITHMS[i]}")
print()
while(alg_sol := int(input("Input the n° of the algorithm for the solving: ")) not in range(len(MazeSolver.ALGORITHMS))):
continue
print()
while(width := int(input("Width of the maze: \t")) not in range(1000)):
continue
print()
while(height := int(input("Height of the maze: \t")) not in range(1000)):
continue
m = MazeDrawer(alg_gen, alg_sol, width, height)
print(m.maze)
m.start()
if __name__ == "__main__":
main()
I'm having trouble with the last instruction of my code. Well, I don't understand why, but my print(m.maze) function prints me nothing and all attributs of the maze are False. What is happening? I tried everything but I couldn't find the issue.
As you might have noticed, I'm doing a maze builder and solver. However, when the Maze object is created from the user's input, the maze goes empty for no reason...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
