from __future__ import annotations from abc import ABC, abstractmethod from dataclasses import dataclass, field from typing import Any from .models import Cell, Maze @dataclass(frozen=True) class Event: event_type: str payload: dict[str, Any] = field(default_factory=dict) class Observer(ABC): @abstractmethod def update(self, event: Event) -> None: raise NotImplementedError class ConsoleView(Observer): def update(self, event: Event) -> None: if event.event_type == "search_started": print(f"Search started: {event.payload['strategy']}") elif event.event_type in {"path_found", "path_not_found"}: stats = event.payload["stats"] print( f"{event.event_type}: strategy={stats.strategy_name}, " f"time={stats.time_ms:.3f} ms, visited={stats.visited_cells}, " f"path_length={stats.path_length}" ) def render( self, maze: Maze, player_position: Cell | None = None, path: list[Cell] | None = None, ) -> str: return maze.to_text(path=path, player=player_position)