diff --git a/VolkovVA/cod.py b/VolkovVA/cod.py index e796ed3..97ff105 100644 --- a/VolkovVA/cod.py +++ b/VolkovVA/cod.py @@ -1,8 +1,9 @@ from collections import deque import heapq import time +from abc import ABC, abstractmethod -# --- Модель --- +# Модель class Cell: def __init__(self, x, y, is_wall=False, is_start=False, is_exit=False): self.x = x @@ -37,16 +38,14 @@ class Maze: neighbors.append(neighbor) return neighbors -# --- Строитель +# Строитель class MazeBuilder: def buildFromFile(self, filename): with open(filename, 'r') as f: lines = f.readlines() - height = len(lines) width = len(lines[0].strip()) maze = Maze(width, height) - for y, line in enumerate(lines): for x, char in enumerate(line.strip()): cell = maze.get_cell(x, y) @@ -61,6 +60,7 @@ class MazeBuilder: raise ValueError("Лабиринт сломан") return maze +# Strategy class PathFindingStrategy: def findPath(self, maze, start, exit): raise NotImplementedError("Этот метод должен быть реализован в стратегии!") @@ -77,7 +77,6 @@ class BFSStrategy(PathFindingStrategy): queue = deque([start]) parents = {start: None} start.visited = True - while queue: current = queue.popleft() if current == exit: @@ -97,12 +96,10 @@ class AStarStrategy(PathFindingStrategy): heap = [(0, start)] parents = {start: None} g_score = {start: 0} - while heap: _, current = heapq.heappop(heap) if current == exit: return self._reconstruct_path(parents, exit) - for neighbor in maze.get_neighbors(current): new_g = g_score[current] + 1 if new_g < g_score.get(neighbor, float('inf')): @@ -112,41 +109,71 @@ class AStarStrategy(PathFindingStrategy): heapq.heappush(heap, (f, neighbor)) return [] +# Статистика class SearchStats: def __init__(self, time_ms, visited, length): self.time_ms = time_ms self.visited = visited self.length = length +# Паттерн Observer +class Observer(ABC): + @abstractmethod + def update(self, event: str, data=None): + pass + +class ConsoleView(Observer): + def update(self, event: str, data=None): + if event == "path_found": + print(f"Событие '{event}': время={data.time_ms:.2f}мс, посещено={data.visited}, путь={data.length}") + elif event == "maze_loaded": + print(f"Событие '{event}': Лабиринт загружен.") + +# --- 6. Оркестратор (MazeSolver) --- class MazeSolver: def __init__(self, maze): self.maze = maze self.strat = None + self._observers = [] + + def attach(self, observer: Observer): + self._observers.append(observer) + + def notify(self, event: str, data=None): + for observer in self._observers: + observer.update(event, data) def setStrategy(self, strategy): self.strat = strategy def solve(self): - if not self.strat: - return None + if not self.strat: return None t0 = time.perf_counter() path = self.strat.findPath(self.maze, self.maze.start_cell, self.maze.exit_cell) t1 = time.perf_counter() - # Считаем посещенные ячейки visited_count = sum(c.visited for row in self.maze.cells for c in row) + stats = SearchStats((t1 - t0) * 1000, visited_count, len(path)) - return SearchStats((t1 - t0) * 1000, visited_count, len(path)) + self.notify("path_found", stats) + return stats +# --- Запуск --- if __name__ == "__main__": builder = MazeBuilder() try: path = r"C:\Users\vva26\2026-rff_mp\VolkovVA\docs\data\maze.txt" maze = builder.buildFromFile(path) solver = MazeSolver(maze) + + # Регистрация наблюдателя + solver.attach(ConsoleView()) + solver.notify("maze_loaded") + + # Решение solver.setStrategy(BFSStrategy()) - stats = solver.solve() - print(f"BFS: {stats.time_ms:.2f}мс, посещено: {stats.visited}, путь: {stats.length}") + solver.solve() + except Exception as e: print(f"Ошибка: {e}") \ No newline at end of file