import os from abc import ABC, abstractmethod from typing import Optional, List from models import Maze, Cell class Observer(ABC): @abstractmethod def update(self, event: str, data=None): pass class ConsoleView(Observer): WALL_CHAR = '■' START_CHAR = 'S' EXIT_CHAR = 'E' PATH_CHAR = '•' PLAYER_CHAR = 'P' PASSAGE_CHAR = ' ' def update(self, event: str, data=None): if event == "search_started": print(f"\n Запущен поиск с помощью: {data['strategy']}") elif event == "path_found": stats = data['stats'] print(f" Путь найден! {stats}") elif event == "path_not_found": stats = data['stats'] print(f" Путь НЕ найден. {stats}") elif event == "step": self.render(data['maze'], data['current'], data.get('path')) @staticmethod def render(maze: Maze, player_pos: Optional[Cell] = None, path: Optional[List[Cell]] = None): os.system('cls' if os.name == 'nt' else 'clear') path_set = set(path) if path else set() print("┌" + "─" * maze.width + "┐") for y in range(maze.height): row_str = "│" for x in range(maze.width): cell = maze.getCell(x, y) if player_pos and cell == player_pos: row_str += ConsoleView.PLAYER_CHAR elif cell.isStart: row_str += ConsoleView.START_CHAR elif cell.isExit: row_str += ConsoleView.EXIT_CHAR elif cell in path_set: row_str += ConsoleView.PATH_CHAR elif cell.isWall: row_str += ConsoleView.WALL_CHAR else: row_str += ConsoleView.PASSAGE_CHAR row_str += "│" print(row_str) print("└" + "─" * maze.width + "┘")