2026-rff_mp/smirnovad/lab2/docs/data/main.py
2026-05-17 16:50:47 +03:00

128 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from maze_builder import TextFileMazeBuilder
from maze_solver import MazeSolver
from strategies import BFSStrategy, DFSStrategy, AStarStrategy, DijkstraStrategy
from observer import ConsoleView
from command import Player, MoveCommand
STRATEGIES = {
"1": ("BFS", BFSStrategy),
"2": ("DFS", DFSStrategy),
"3": ("A*", AStarStrategy),
"4": ("Dijkstra", DijkstraStrategy),
}
DIRECTION_MAP = {
"w": (0, -1),
"s": (0, 1),
"a": (-1, 0),
"d": (1, 0),
}
def choose_strategy():
print("\nВыберите алгоритм:")
for key, (name, _) in STRATEGIES.items():
print(f" {key}. {name}")
choice = input("Ваш выбор: ").strip()
if choice not in STRATEGIES:
print("Неверный выбор, используется BFS.")
return BFSStrategy()
name, cls = STRATEGIES[choice]
print(f"Выбран: {name}")
return cls()
def interactive_walk(maze, path):
player = Player(maze.start)
view = ConsoleView()
history: list[MoveCommand] = []
print("\n=== Ручное управление ===")
print("W/A/S/D — движение, U — отмена, Q — выход")
view.render(maze, path=path, player=player.current_cell)
while True:
cmd_input = input("Ход: ").strip().lower()
if cmd_input == "q":
break
if cmd_input == "u":
if history:
history.pop().undo()
view.render(maze, path=path, player=player.current_cell)
else:
print("Нет ходов для отмены.")
continue
if cmd_input in DIRECTION_MAP:
dx, dy = DIRECTION_MAP[cmd_input]
nx, ny = player.current_cell.x + dx, player.current_cell.y + dy
if 0 <= nx < maze.width and 0 <= ny < maze.height:
target = maze.get_cell(nx, ny)
cmd = MoveCommand(player, target, maze)
cmd.execute()
history.append(cmd)
view.render(maze, path=path, player=player.current_cell)
if player.current_cell == maze.exit:
print("🎉 Вы достигли выхода!")
break
else:
print("За пределами лабиринта.")
else:
print("Неизвестная команда.")
def main():
print("Решатель лабиринтов")
mazes_dir = "mazes"
if os.path.isdir(mazes_dir):
files = [f for f in sorted(os.listdir(mazes_dir)) if f.endswith(".txt")]
if files:
print("\nДоступные лабиринты:")
for i, f in enumerate(files, 1):
print(f" {i}. {f}")
choice = input("Выберите номер (или введите путь): ").strip()
if choice.isdigit() and 1 <= int(choice) <= len(files):
maze_path = os.path.join(mazes_dir, files[int(choice) - 1])
else:
maze_path = choice
else:
maze_path = input("Путь к файлу лабиринта: ").strip()
else:
maze_path = input("Путь к файлу лабиринта: ").strip()
builder = TextFileMazeBuilder()
try:
maze = builder.build_from_file(maze_path)
print(f"\nЛабиринт загружен: {maze.width}×{maze.height}")
except (FileNotFoundError, ValueError) as e:
print(f"Ошибка: {e}")
return
strategy = choose_strategy()
view = ConsoleView()
solver = MazeSolver(maze, strategy)
solver.add_observer(view)
stats = solver.solve()
print(f"\n── Статистика ──────────────────")
print(f" Время: {stats.time_ms:.4f} мс")
print(f" Посещено клеток: {stats.visited_cells}")
print(f" Длина пути: {stats.path_length}")
if stats.path:
walk = input("\nЗапустить ручное управление? (y/n): ").strip().lower()
if walk == "y":
interactive_walk(maze, stats.path)
if __name__ == "__main__":
main()