118 lines
4.5 KiB
Python
118 lines
4.5 KiB
Python
import os
|
||
from .observer import Observer, Event, EventType
|
||
|
||
class ConsoleView(Observer):
|
||
"""Консольное отображение лабиринта"""
|
||
|
||
def __init__(self):
|
||
self.maze = None
|
||
self.player_pos = None
|
||
self.path = []
|
||
self.current_strategy = None
|
||
self.messages = []
|
||
|
||
def update(self, event: Event):
|
||
event_type = event.event_type
|
||
data = event.data
|
||
|
||
if event_type == EventType.MAZE_LOADED:
|
||
self.maze = data
|
||
self._log(f"Лабиринт загружен: {self.maze.width}x{self.maze.height}")
|
||
|
||
elif event_type == EventType.PATH_FOUND:
|
||
self.path = data if data else []
|
||
self._log(f"Путь найден! Длина: {len(self.path)} шагов")
|
||
|
||
elif event_type == EventType.PATH_NOT_FOUND:
|
||
self.path = []
|
||
self._log(f"Путь не найден!")
|
||
|
||
elif event_type == EventType.PLAYER_MOVED:
|
||
self.player_pos = data
|
||
self._log(f"Игрок переместился на ({data.x}, {data.y})")
|
||
|
||
elif event_type == EventType.SEARCH_START:
|
||
self._log(f"Начинаем поиск пути...")
|
||
|
||
elif event_type == EventType.SEARCH_END:
|
||
self._log(f"Поиск завершён")
|
||
|
||
elif event_type == EventType.ERROR:
|
||
self._log(f"Ошибка: {data}")
|
||
|
||
elif event_type == EventType.UNDO:
|
||
self._log(f"Отмена последнего действия")
|
||
|
||
# После каждого события перерисовываем
|
||
self.render()
|
||
|
||
def render(self):
|
||
"""Отрисовывает лабиринт в консоли"""
|
||
if not self.maze:
|
||
print("Лабиринт не загружен")
|
||
return
|
||
|
||
# Очищаем консоль
|
||
os.system('cls' if os.name == 'nt' else 'clear')
|
||
|
||
print("=" * 60)
|
||
print("ЛАБИРИНТ")
|
||
if self.current_strategy:
|
||
print(f"Алгоритм: {self.current_strategy}")
|
||
print("=" * 60)
|
||
|
||
# Создаём множество клеток пути для быстрого доступа
|
||
path_set = set(self.path) if self.path else set()
|
||
|
||
# Верхняя граница с координатами
|
||
print(" " + " ".join(f"{x:2}" for x in range(self.maze.width)))
|
||
|
||
for y in range(self.maze.height):
|
||
# Номер строки
|
||
line = f"{y:2} │ "
|
||
|
||
for x in range(self.maze.width):
|
||
cell = self.maze.get_cell(x, y)
|
||
|
||
# Определяем символ для отображения
|
||
if self.player_pos and cell == self.player_pos:
|
||
line += "🎮 "
|
||
elif cell == self.maze.start:
|
||
line += "🚩 "
|
||
elif cell == self.maze.exit:
|
||
line += "🏁 "
|
||
elif cell in path_set:
|
||
line += "● "
|
||
elif cell.is_wall:
|
||
line += "██ "
|
||
else:
|
||
line += "· "
|
||
|
||
print(line)
|
||
|
||
print("Условные обозначения:")
|
||
print(" ██ - стена · - проход ● - путь")
|
||
print(" 🚩 - старт 🏁 - выход 🎮 - игрок")
|
||
if self.current_strategy:
|
||
print(f" Алгоритм: {self.current_strategy}")
|
||
|
||
# Выводим сообщения
|
||
if self.messages:
|
||
print("\nСООБЩЕНИЯ:")
|
||
for msg in self.messages[-5:]: # Показываем последние 5 сообщений
|
||
print(f" {msg}")
|
||
print("Команды: W/A/S/D - движение, U - отмена, Q - выход")
|
||
|
||
def set_strategy(self, strategy_name: str):
|
||
"""Устанавливает имя текущей стратегии для отображения"""
|
||
self.current_strategy = strategy_name
|
||
|
||
def _log(self, message: str):
|
||
"""Добавляет сообщение в лог"""
|
||
self.messages.append(message)
|
||
if len(self.messages) > 10:
|
||
self.messages.pop(0)
|
||
|
||
def clear_messages(self):
|
||
"""Очищает сообщения"""
|
||
self.messages = [] |