forked from UNN/2026-rff_mp
60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
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 + "┘") |