diff --git a/konnovaea/maze_solver.py b/konnovaea/maze_solver.py index 8fbc904..ec7d079 100644 --- a/konnovaea/maze_solver.py +++ b/konnovaea/maze_solver.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod from collections import deque import heapq import time - +import os class Cell: def __init__(self, x, y): @@ -177,4 +177,158 @@ class MazeSolver: end_time = time.perf_counter() return SearchStats(path, (end_time - start_time) * 1000, visited) +class Observer(ABC): + + @abstractmethod + def update(self, event, data=None): + pass + +class ConsoleView(Observer): + + def __init__(self): + self.events = [] + + def update(self, event, data=None): + self.events.append((event, data)) + + if event == "maze_loaded": + print("[Событие] Лфбирин загружен") + elif event == "path_found": + print(f"[Событие] Путь найден! Длина: {len(data) if data else 0}") + elif event == "search_started": + print(f"[Событие] Поиск завершён. Время: {data:.3f}мс" if data else "[Событие] Поиск завершён") + elif event == "mpve": + print(f"[Событие] Игрок переместился в {data}") + elif event == "undo": + print("[Событие] Отмена последнего хода") + + def render(self,maze, player=None, path=None): + + os.system('cls' if os.name == 'nt' else 'clear') + + print("Лабиринт") + + for y in range(maze.height): + row = "" + for x in range(maze.width): + cell = maze.get_cell(x,y) + + if player and cell == player.current_cell: + row += "p " #игрок + elif path and cell in path: + row += "* " #путь + elif cell.is_wall: + row += "# " #стена + elif cell.is_start: + row += "S " #старт + elif cell.is_exit: + row += "E " #выход + else: + row += ". " #прозод + print(row) + + print("Управление: W/A/S/D - движение, U - отмена, Q - выход") + +class Command(ABC): + + @abstractmethod + def execute(self): + pass + + @abstractmethod + def undo(self): + pass + +class Player: + + def __init__(self, start_cell): + self.current_cell = start_cell + self.start_cell = start_cell + + def move_to(self, cell): + self.current_cell = cell + + def resent(self): + self.current_cell = self.start_cell + + def __repr__(self): + return f"Player at ({self.current_cell.x}, {self.current_cell.y})" + +class MoveCommand(Command): + + def __init__(self, player, new_cell, view): + self.player = player + self.new_cell = new_cell + self.old_cell = player.current_cell + self.view = view + + def execute(self): + self.player.move_to(self.new_cell) + self.view.update("undo", None) + +class GameController: + + def __init__(self, maze, view): + self.maze = maze + self.view = view + self.player = Player(maze.start) + self.command_history = [] + + def get_cell_in_direction(self, direction): + + x, y = self.player.current_cell.x, self.player.current_cell.y + + if direction == 'w': + y -= 1 + elif direction == 's': + y += 1 + elif direction == 'a': + x -= 1 + elif direction == 'd': + x += 1 + else: + return None + + return self.maze.get_cell(x, y) + + def try_move(self, direction): + + new_cell = self.get_cell_in_direction(direction) + + if new_cell and new_cell.is_passable(): + command = MoveCommand(self.player, new_cell, self.view) + command.execute() + self.command_history.append(command) + + if new_cell.is_exit: + self.view.update("path_found", []) + print("Вы нашли выход.") + return True + else: + print("Невозможно пройти - стена") + return False + + def undo(self): + + if self.command_history: + command = self.command_history.pop() + command.undo() + else: + print("Нечего отменять") + + def visualize_path(self, path): + self.view.render(self.maze, self.player, path) + + def run_manual_mode(self): + + while True: + self.view.render(self.maze, self.player) + + command = input("Введите команду: ").lower().strip() + + + + + +