[2] feat - Observer и консольная визуализация
This commit is contained in:
parent
a966076c00
commit
2e68f1a389
|
|
@ -271,6 +271,8 @@ class Pathfinder:
|
||||||
t1 = time.perf_counter()
|
t1 = time.perf_counter()
|
||||||
elapsed_ms = (t1 - t0) * 1000
|
elapsed_ms = (t1 - t0) * 1000
|
||||||
|
|
||||||
|
self.notify("path_found", path)
|
||||||
|
|
||||||
return PerformanceData(elapsed_ms, self._algorithm.visited_nodes(), len(path))
|
return PerformanceData(elapsed_ms, self._algorithm.visited_nodes(), len(path))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -281,19 +283,63 @@ class PerformanceData:
|
||||||
self.path_length = length
|
self.path_length = length
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------- Наблюдатель и отображение -----------------------------
|
||||||
|
class EventListener:
|
||||||
|
def update(self, event_type, data):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleDisplay(EventListener):
|
||||||
|
def __init__(self):
|
||||||
|
self._last_path = None
|
||||||
|
|
||||||
|
def update(self, event_type, data):
|
||||||
|
if event_type == "maze_loaded":
|
||||||
|
self._render_maze(data)
|
||||||
|
elif event_type == "path_found":
|
||||||
|
self._last_path = data
|
||||||
|
self._render_path(data)
|
||||||
|
|
||||||
|
def _render_maze(self, maze):
|
||||||
|
os.system('cls' if os.name == 'nt' else 'clear')
|
||||||
|
print("=" * (maze.width * 2 + 4))
|
||||||
|
print(" LABYRINTH")
|
||||||
|
print("=" * (maze.width * 2 + 4))
|
||||||
|
|
||||||
|
for y in range(maze.height):
|
||||||
|
print(" ", end='')
|
||||||
|
for x in range(maze.width):
|
||||||
|
cell = maze.cell_at(x, y)
|
||||||
|
if cell == maze.start:
|
||||||
|
print('S', end=' ')
|
||||||
|
elif cell == maze.exit:
|
||||||
|
print('E', end=' ')
|
||||||
|
elif cell.is_wall:
|
||||||
|
print('#', end=' ')
|
||||||
|
else:
|
||||||
|
print('.', end=' ')
|
||||||
|
print()
|
||||||
|
print("=" * (maze.width * 2 + 4))
|
||||||
|
print(" S - start E - exit # - wall . - path")
|
||||||
|
|
||||||
|
def _render_path(self, path):
|
||||||
|
if not path:
|
||||||
|
print("\n Path not found!")
|
||||||
|
return
|
||||||
|
print(f"\n Path found! Length: {len(path)}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
builder = TxtLabyrinthBuilder()
|
builder = TxtLabyrinthBuilder()
|
||||||
maze = builder.build_from_file("maze/level1.txt")
|
maze = builder.build_from_file("maze/level1.txt")
|
||||||
|
|
||||||
|
view = ConsoleDisplay()
|
||||||
|
view.update("maze_loaded", maze)
|
||||||
|
|
||||||
pf = Pathfinder(maze)
|
pf = Pathfinder(maze)
|
||||||
pf.set_algorithm(BFS())
|
pf.attach(view)
|
||||||
stats = pf.solve()
|
|
||||||
print(f"BFS: {stats.time_ms:.3f}ms, visited={stats.visited_cells}, length={stats.path_length}")
|
|
||||||
|
|
||||||
pf.set_algorithm(DFS())
|
for algo, name in [(BFS(), "BFS"), (DFS(), "DFS"), (AStar(), "A*")]:
|
||||||
|
pf.set_algorithm(algo)
|
||||||
stats = pf.solve()
|
stats = pf.solve()
|
||||||
print(f"DFS: {stats.time_ms:.3f}ms, visited={stats.visited_cells}, length={stats.path_length}")
|
print(f"{name}: {stats.time_ms:.3f}ms, visited={stats.visited_cells}, length={stats.path_length}")
|
||||||
|
|
||||||
pf.set_algorithm(AStar())
|
|
||||||
stats = pf.solve()
|
|
||||||
print(f"A*: {stats.time_ms:.3f}ms, visited={stats.visited_cells}, length={stats.path_length}")
|
|
||||||
Loading…
Reference in New Issue
Block a user