from abc import ABC, abstractmethod from typing import Optional from models import Cell, Maze class Player: def __init__(self, start_cell: Cell): self.current_cell = start_cell def move_to(self, new_cell: Cell) -> None: self.current_cell = new_cell class Command(ABC): @abstractmethod def execute(self) -> bool: pass @abstractmethod def undo(self) -> None: pass class MoveCommand(Command): def __init__(self, player: Player, maze: Maze, direction: str): self.player = player self.maze = maze self.direction = direction self.previous_cell: Optional[Cell] = None self.new_cell: Optional[Cell] = None def _get_target_cell(self) -> Optional[Cell]: x, y = self.player.current_cell.x, self.player.current_cell.y if self.direction == 'w': y -= 1 elif self.direction == 's': y += 1 elif self.direction == 'a': x -= 1 elif self.direction == 'd': x += 1 else: return None return self.maze.get_cell(x, y) def execute(self) -> bool: self.previous_cell = self.player.current_cell self.new_cell = self._get_target_cell() if self.new_cell and self.new_cell.is_passable(): self.player.move_to(self.new_cell) return True return False def undo(self) -> None: if self.previous_cell: self.player.move_to(self.previous_cell)