"""Паттерн Observer - визуализация лабиринта""" from abc import ABC, abstractmethod from typing import List, Optional, Any from models import Cell, Maze class Observer(ABC): """Интерфейс наблюдателя""" @abstractmethod def update(self, event_type: str, data: Any = None) -> None: pass class Subject: """Субъект для управления наблюдателями""" def __init__(self): self._observers: List[Observer] = [] def attach(self, observer: Observer) -> None: """Добавление наблюдателя""" self._observers.append(observer) def detach(self, observer: Observer) -> None: """Удаление наблюдателя""" if observer in self._observers: self._observers.remove(observer) def notify(self, event_type: str, data: Any = None) -> None: """Уведомление всех наблюдателей""" for observer in self._observers: observer.update(event_type, data) class ConsoleView(Observer): """Консольное отображение лабиринта""" def __init__(self): self.last_path: List[Cell] = [] self.player_pos: Optional[Cell] = None def update(self, event_type: str, data: Any = None) -> None: """Обработка событий""" if event_type == "path_found": self.last_path = data.get("path", []) print(f"\n=== Путь найден! Длина: {len(self.last_path)} ===") self.render(data.get("maze"), None, self.last_path) elif event_type == "path_not_found": print("\n=== Путь не найден! ===") elif event_type == "player_moved": self.player_pos = data.get("position") if data.get("redraw", True): self.render(data.get("maze"), self.player_pos, self.last_path) elif event_type == "maze_loaded": print("Лабиринт загружен") self.render(data.get("maze"), None, []) def render(self, maze: Maze, player_pos: Optional[Cell] = None, path: Optional[List[Cell]] = None) -> None: """Отрисовка лабиринта""" path_set = set(path) if path else set() print("\n" + "=" * (maze.width + 2)) for y in range(maze.height): line = "|" for x in range(maze.width): cell = maze.get_cell(x, y) if player_pos and cell == player_pos: line += "P" elif cell == maze.start: line += "S" elif cell == maze.exit: line += "E" elif cell in path_set and cell != maze.start and cell != maze.exit: line += "." elif cell.is_wall: line += "#" else: line += " " line += "|" print(line) print("=" * (maze.width + 2)) if path: print(f"Длина пути: {len(path)}")