from abc import ABC, abstractmethod from typing import List from maze import Maze, Cell class Command(ABC): """Интерфейс команды (Command pattern).""" @abstractmethod def execute(self) -> bool: pass @abstractmethod def undo(self): pass class Player: """Игрок, перемещающийся по лабиринту.""" def __init__(self, cell: Cell): self.current_cell = cell self._history: List[Cell] = [] def move_to(self, cell: Cell): self._history.append(self.current_cell) self.current_cell = cell def move_back(self): if self._history: self.current_cell = self._history.pop() return self.current_cell return None def __repr__(self): return f"Player({self.current_cell.x}, {self.current_cell.y})" class MoveCommand(Command): """Команда перемещения игрока.""" DIRECTIONS = { 'W': (0, -1), 'S': (0, 1), 'A': (-1, 0), 'D': (1, 0), } def __init__(self, player: Player, maze: Maze, direction: str): self.player = player self.maze = maze self.direction = direction.upper() self._previous_cell = None self._executed = False def execute(self) -> bool: if self.direction not in self.DIRECTIONS: return False dx, dy = self.DIRECTIONS[self.direction] new_x = self.player.current_cell.x + dx new_y = self.player.current_cell.y + dy new_cell = self.maze.get_cell(new_x, new_y) if new_cell and new_cell.is_passable(): self._previous_cell = self.player.current_cell self.player.move_to(new_cell) self._executed = True return True return False def undo(self): if self._executed and self._previous_cell: self.player.current_cell = self._previous_cell self._executed = False self._previous_cell = None