diff --git a/ProninVV/task-2-oop/Command.py b/ProninVV/task-2-oop/Command.py new file mode 100644 index 0000000..c9e391d --- /dev/null +++ b/ProninVV/task-2-oop/Command.py @@ -0,0 +1,45 @@ +from abc import ABC, abstractmethod + + +class Player: + def __init__(self, start_cell): + self.current_cell = start_cell + + +class Command(ABC): + @abstractmethod + def execute(self) -> bool: + """Выполняет действие. Возвращает True, если ход успешен.""" + pass + + @abstractmethod + def undo(self) -> None: + """Откатывает действие назад.""" + pass + + +class MoveCommand(Command): + def __init__(self, player: Player, maze, dx: int, dy: int): + self.player = player + self.maze = maze + self.dx = dx + self.dy = dy + self.previous_cell = None + + def execute(self) -> bool: + new_x = self.player.current_cell.x + self.dx + new_y = self.player.current_cell.y + self.dy + + next_cell = self.maze.getCell(new_x, new_y) + + if next_cell and next_cell.isPassable(): + self.previous_cell = self.player.current_cell + self.player.current_cell = next_cell + return True + + print("Ошибка: Там стена или край лабиринта!") + return False + + def undo(self) -> None: + if self.previous_cell: + self.player.current_cell = self.previous_cell diff --git a/ProninVV/task-2-oop/ConsoleView.py b/ProninVV/task-2-oop/ConsoleView.py new file mode 100644 index 0000000..c122c5e --- /dev/null +++ b/ProninVV/task-2-oop/ConsoleView.py @@ -0,0 +1,40 @@ +from Observer import Observer, Event + + +class ConsoleView(Observer): + def update(self, event: Event) -> None: + if event.type == "maze_loaded": + print("\n[Система] Лабиринт успешно загружен!") + self.render(event.data.get("maze")) + + elif event.type == "path_found": + print("\n[Система] Алгоритм нашёл решение!") + self.render(event.data.get("maze"), path=event.data.get("path")) + + elif event.type == "move": + print( + f"\n[Игрок] Переместился в точку: ({event.data.get('player_pos').x}, {event.data.get('player_pos').y})") + self.render(event.data.get("maze"), + player_position=event.data.get("player_pos")) + + def render(self, maze, player_position=None, path=None) -> None: + path_set = set(path) if path else set() + + for y in range(maze.height): + row_chars = [] + for x in range(maze.width): + cell = maze.getCell(x, y) + + if player_position and cell == player_position: + row_chars.append("P") + elif cell.isStart: + row_chars.append("S") + elif cell.isExit: + row_chars.append("E") + elif cell in path_set: + row_chars.append(".") + elif cell.isWall: + row_chars.append("#") + else: + row_chars.append(" ") + print("".join(row_chars)) diff --git a/ProninVV/task-2-oop/Observer.py b/ProninVV/task-2-oop/Observer.py new file mode 100644 index 0000000..ea1a1dd --- /dev/null +++ b/ProninVV/task-2-oop/Observer.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod + + +class Event: + def __init__(self, type: str, data: dict = None): + self.type = type # "maze_loaded", "move", "path_found" + self.data = data if data else {} + + +class Observer(ABC): + @abstractmethod + def update(self, event: Event) -> None: + pass