observer and command

реализованы классы визуализации и пошагового решения
This commit is contained in:
novikovsd 2026-05-25 09:20:38 +00:00
parent 80d51b3f93
commit 9ae55f1244

View File

@ -234,11 +234,105 @@ class MazeSolver:
return path, stats
class Observer(ABC):
@abstractmethod
def update(self, event: str, data: Any):
pass
class ConsoleView(Observer):
def __init__(self):
self.player_pos = None
self.path = []
def update(self, event: str, data: Any):
if event == "maze_loaded":
self.maze = data["maze"]
self.render()
elif event == "player_moved":
self.player_pos = data["player_cell"]
self.render()
elif event == "path_found":
self.path = data["path"]
self.render()
elif event == "solved":
self.path = data["path"]
self.render()
def render(self, maze: Maze = None, player_cell: Cell = None, path: List[Cell] = None):
if maze:
self.maze = maze
if player_cell:
self.player_pos = player_cell
if path is not None:
self.path = path
if not hasattr(self, 'maze'):
print("Нет лабиринта для отображения")
return
for y in range(self.maze.height):
row = ""
for x in range(self.maze.width):
cell = self.maze.get_cell(x, y)
if cell is None:
row += " "
continue
if self.player_pos and cell == self.player_pos:
row += "P"
elif cell == self.maze.start:
row += "S"
elif cell == self.maze.exit:
row += "E"
elif self.path and cell in self.path:
row += "."
elif cell.is_wall:
row += "#"
else:
row += " "
print(row)
print()
class MoveCommand(ABC):
@abstractmethod
def execute(self):
pass
@abstractmethod
def undo(self):
pass
class Player:
def __init__(self, start_cell: Cell):
self.current_cell = start_cell
class MoveCommandImpl(MoveCommand):
def move_to(self, cell: Cell):
self.current_cell = cell
class MoveCommandImpl(MoveCommand):
def __init__(self, player: Player, direction: str, maze: Maze):
self.player = player
self.direction = direction
self.maze = maze
self.previous_cell = player.current_cell
def execute(self):
dx, dy = 0, 0
if self.direction == 'w':
dy = -1
elif self.direction == 's':
dy = 1
elif self.direction == 'a':
dx = -1
elif self.direction == 'd':
dx = 1
else:
return False
new_x = self.player.current_cell.x + dx
new_y = self.player.current_cell.y + dy
new_cell = self.maze.get_cell(new_x, new_y)
if new_cell and new_cell.is_passable():
self.player.move_to(new_cell)
return True
return False
def undo(self):
self.player.move_to(self.previous_cell)