diff --git a/lukovnikovde/docs/data/2-nd-exercise/main.py b/lukovnikovde/docs/data/2-nd-exercise/main.py index 1e0c35a9..52916468 100644 --- a/lukovnikovde/docs/data/2-nd-exercise/main.py +++ b/lukovnikovde/docs/data/2-nd-exercise/main.py @@ -4,9 +4,8 @@ from collections import deque import heapq import time - +# ---------- 1. Модель клетки и лабиринта ---------- class Tile: - """Клетка лабиринта.""" def __init__(self, x, y): self.x = x self.y = y @@ -19,7 +18,6 @@ class Tile: class Labyrinth: - """Модель лабиринта.""" def __init__(self, width, height): self.width = width self.height = height @@ -64,6 +62,7 @@ class Labyrinth: return result +# ---------- 2. Загрузка лабиринта из файла ---------- class LabyrinthLoader: def load(self, filename): raise NotImplementedError @@ -96,6 +95,7 @@ class TextLabyrinthLoader(LabyrinthLoader): return lab +# ---------- 3. Алгоритмы поиска пути (стратегии) ---------- class Pathfinder: def find_path(self, lab, start, goal): raise NotImplementedError @@ -186,10 +186,19 @@ class AStar(Pathfinder): return [] +# ---------- 4. Оркестратор с поддержкой наблюдателей ---------- class LabyrinthSolver: def __init__(self, lab): self.lab = lab self.strategy = None + self.observers = [] + + def attach(self, obs): + self.observers.append(obs) + + def notify(self, event, data): + for obs in self.observers: + obs.notify(event, data) def set_strategy(self, strategy): self.strategy = strategy @@ -200,6 +209,7 @@ class LabyrinthSolver: t0 = time.perf_counter() path = self.strategy.find_path(self.lab, self.lab.start_tile, self.lab.exit_tile) t1 = time.perf_counter() + self.notify("path_found", path) return { 'time_ms': (t1 - t0) * 1000, 'visited': self.strategy.visited_count(), @@ -207,6 +217,7 @@ class LabyrinthSolver: } +# ---------- 5. Визуализация (наблюдатель) ---------- class EventListener: def notify(self, event, data): raise NotImplementedError @@ -278,6 +289,7 @@ class ConsoleRenderer(EventListener): print(f"\n Путь найден! Длина = {len(path)}") +# ---------- 6. Игрок и команды с отменой ---------- class Walker: def __init__(self, start_tile, lab): self.current = start_tile @@ -331,14 +343,66 @@ class MoveAction(Action): return False +# ---------- 7. Главный интерактивный цикл (коммит №4) ---------- if __name__ == "__main__": + # Загружаем лабиринт (предполагается, что файл maze/maze1.txt существует) loader = TextLabyrinthLoader() lab = loader.load("maze/maze1.txt") - print("Загружен лабиринт, пробуем BFS...") + + player = Walker(lab.start_tile, lab) + view = ConsoleRenderer(player) + view.notify("maze_loaded", lab) + solver = LabyrinthSolver(lab) - solver.set_strategy(BFS()) - stats = solver.solve() - if stats['length'] > 0: - print(f"BFS: время={stats['time_ms']:.3f}мс, посещено={stats['visited']}, длина={stats['length']}") - else: - print("Путь не найден") \ No newline at end of file + solver.attach(view) + + print("\n УПРАВЛЕНИЕ:") + print(" H (влево) J (вниз) K (вверх) L (вправо)") + print(" U - отменить ход Q - выход") + print("\n АВТОПОИСК:") + print(" B - BFS D - DFS A - A*") + print("\n" + "=" * 50) + + command_stack = [] + while True: + key = input("\n Команда > ").lower() + if key == 'q': + print("\n До свидания!") + break + elif key == 'b': + solver.set_strategy(BFS()) + stats = solver.solve() + if stats: + print(f"\n BFS: время={stats['time_ms']:.3f}мс, посещено={stats['visited']}, длина={stats['length']}") + elif key == 'd': + solver.set_strategy(DFS()) + stats = solver.solve() + print(f"\n DFS: время={stats['time_ms']:.3f}мс, посещено={stats['visited']}, длина={stats['length']}") + elif key == 'a': + solver.set_strategy(AStar()) + stats = solver.solve() + print(f"\n A*: время={stats['time_ms']:.3f}мс, посещено={stats['visited']}, длина={stats['length']}") + elif key in ['h', 'j', 'k', 'l']: + dirs = {'h': (-1,0), 'l': (1,0), 'k': (0,-1), 'j': (0,1)} + act = MoveAction(player, dirs[key][0], dirs[key][1], lab) + if act.do(): + command_stack.append(act) + view.notify("player_moved", lab) + if player.current == lab.exit_tile: + print("\n ПОЗДРАВЛЯЮ! ВЫ НАШЛИ ВЫХОД!") + print(f" Сделано ходов: {len(command_stack)}") + break + else: + print("\n Туда нельзя – стена!") + elif key == 'u': + if command_stack: + cmd = command_stack.pop() + cmd.undo() + view.notify("player_moved", lab) + print("\n Отмена последнего хода") + else: + print("\n Нечего отменять") + else: + print("\n Неизвестная команда. Используйте h,j,k,l, u, b, d, a, q") + + print("\n Игра окончена. Спасибо!") \ No newline at end of file