forked from UNN/2026-rff_mp
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""
|
||
Этап 5.2: Паттерн Command — пошаговое перемещение игрока с отменой хода.
|
||
|
||
Зачем Command?
|
||
Каждое перемещение инкапсулировано в объекте. Это позволяет:
|
||
- хранить историю ходов
|
||
- отменять последний ход (undo) через Ctrl+Z
|
||
- повторять ходы
|
||
"""
|
||
|
||
from abc import ABC, abstractmethod
|
||
from maze_model import Cell, Maze
|
||
|
||
|
||
class Command(ABC):
|
||
"""Интерфейс команды."""
|
||
|
||
@abstractmethod
|
||
def execute(self) -> None:
|
||
...
|
||
|
||
@abstractmethod
|
||
def undo(self) -> None:
|
||
...
|
||
|
||
|
||
class Player:
|
||
"""Хранит текущую позицию игрока в лабиринте."""
|
||
|
||
def __init__(self, start_cell: Cell):
|
||
self.current_cell = start_cell
|
||
|
||
def move_to(self, cell: Cell) -> None:
|
||
self.current_cell = cell
|
||
|
||
def __repr__(self):
|
||
return f"Player@({self.current_cell.x},{self.current_cell.y})"
|
||
|
||
|
||
class MoveCommand(Command):
|
||
"""
|
||
Команда перемещения игрока.
|
||
Сохраняет предыдущую клетку для возможности отмены.
|
||
"""
|
||
|
||
def __init__(self, player: Player, target_cell: Cell, maze: Maze):
|
||
self.player = player
|
||
self.target_cell = target_cell
|
||
self.maze = maze
|
||
self.previous_cell = player.current_cell # для undo
|
||
|
||
def execute(self) -> None:
|
||
self.previous_cell = self.player.current_cell
|
||
if not self.target_cell.is_passable():
|
||
print("Нельзя идти в стену!")
|
||
return
|
||
self.player.move_to(self.target_cell)
|
||
|
||
def undo(self) -> None:
|
||
self.player.move_to(self.previous_cell)
|
||
print(f"Ход отменён. Игрок вернулся в ({self.previous_cell.x}, {self.previous_cell.y})")
|