""" maze_solver/command.py - паттерн Command. Player хранит текущую клетку. MoveCommand двигает игрока в выбранном направлении и помнит предыдущую позицию для undo. Менеджер CommandHistory держит стек выполненных команд. """ from abc import ABC, abstractmethod class Player: """Игрок в лабиринте.""" def __init__(self, cell): self.cell = cell @property def x(self): return self.cell.x @property def y(self): return self.cell.y class Command(ABC): @abstractmethod def execute(self): ... @abstractmethod def undo(self): ... class MoveCommand(Command): """Команда перемещения игрока на одну клетку. direction: одна из 'W','A','S','D' (вверх, влево, вниз, вправо). """ DELTAS = { 'W': (0, -1), 'S': (0, 1), 'A': (-1, 0), 'D': (1, 0), } def __init__(self, maze, player, direction): self.maze = maze self.player = player self.direction = direction.upper() self._prev_cell = None self._executed = False def execute(self): if self.direction not in self.DELTAS: return False dx, dy = self.DELTAS[self.direction] target = self.maze.get_cell(self.player.x + dx, self.player.y + dy) if target is None or not target.is_passable(): return False self._prev_cell = self.player.cell self.player.cell = target self._executed = True return True def undo(self): if not self._executed: return False self.player.cell = self._prev_cell self._executed = False return True class CommandHistory: """Стек выполненных команд (для общего undo).""" def __init__(self): self._stack = [] def do(self, cmd): if cmd.execute(): self._stack.append(cmd) return True return False def undo(self): if not self._stack: return False return self._stack.pop().undo()