2026-rff_mp/sobininaas/Задание2/main.py

136 lines
4.7 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_core import Maze, Cell
from maze_builder import TextMazeBuilder
from pathfinding import BFSSearch, DFSSearch, AStarSearch
from solver import MazeSolver
from patterns import ConsoleObserver, Player, MoveCommand
def select_maze_file() -> str:
print("\n Доступные лабиринты:")
print("1 - small (10×10, демо)")
print("2 - medium (50×50, стандарт)")
print("3 - large (100×100, сложный)")
print("4 - empty (пустой, тест скорости)")
print("5 - no_exit (без выхода, проверка ошибок)")
while True:
choice = input("\nВыберите номер (1-5): ").strip()
mapping = {
'1': 'small.txt', '2': 'medium.txt', '3': 'large.txt',
'4': 'empty.txt', '5': 'no_exit.txt'
}
if choice in mapping:
return mapping[choice]
print(" Неверный ввод. Введите число от 1 до 5.")
def draw_maze(maze: Maze, path=None):
if maze.width > 30 or maze.height > 30:
return False
path_set = set(path) if path else set()
print("\n Карта лабиринта:")
for y in range(maze.height):
row = []
for x in range(maze.width):
cell = maze.cell_at(x, y)
if cell in path_set:
if cell.is_start: row.append('S')
elif cell.is_exit: row.append('E')
else: row.append('*')
else:
row.append(str(cell))
print(''.join(row))
return True
def main():
selected_file = select_maze_file()
maze_path = os.path.join(os.path.dirname(__file__), 'data', selected_file)
try:
builder = TextMazeBuilder()
maze = builder.load(maze_path)
print(f"\nЗагружен: {selected_file} ({maze.width}x{maze.height})")
if not draw_maze(maze):
print(" (слишком большой для отрисовки в консоли)")
except FileNotFoundError:
print(f" Файл {selected_file} не найден в папке data/")
return
except Exception as e:
print(f" Ошибка загрузки: {e}")
return
solver = MazeSolver(maze)
view = ConsoleObserver()
solver.add_observer(view)
strategies = {
"BFS": BFSSearch(),
"DFS": DFSSearch(),
"A*": AStarSearch()
}
results = []
for name, strategy in strategies.items():
solver.set_strategy(strategy)
print(f"\n🔍 {name}:")
stats = solver.solve()
print(f" Время: {stats.time_ms:.3f} мс")
print(f" Клеток посещено: {stats.visited_cells}")
print(f" Длина пути: {stats.path_length}")
if solver.last_path:
if not draw_maze(maze, path=solver.last_path):
print(" (путь не отрисован из-за размера)")
else:
print(" Путь не найден!")
results.append((name, stats))
print(f"{'Алгоритм':<10} {'Время (мс)':<15} {'Посещено':<12} {'Длина':<8}")
for name, stats in results:
print(f"{name:<10} {stats.time_ms:<15.3f} {stats.visited_cells:<12} {stats.path_length:<8}")
# 4. Интерактивный режим (только для маленьких)
if maze.width <= 30 and maze.height <= 30:
if input("\n Запустить интерактивный режим? (y/n): ").lower() == 'y':
interactive_mode(maze)
else:
print("\n Для игры запустите программу ещё раз и выберите small.txt")
def interactive_mode(maze: Maze):
player = Player(maze.start_cell)
view = ConsoleObserver()
history = []
while True:
view.draw(maze, player=player.pos)
if player.pos == maze.exit_cell:
print("\n Ура победа! Выход найден!")
break
move = input("Ход (W/A/S/D, U=отмена, Q=выход): ").upper()
if move == 'Q': break
if move == 'U' and history:
history.pop().undo()
continue
dirs = {'W': (0,-1), 'S': (0,1), 'A': (-1,0), 'D': (1,0)}
if move not in dirs: continue
dx, dy = dirs[move]
new_cell = maze.cell_at(player.pos.x + dx, player.pos.y + dy)
if new_cell and new_cell.passable():
cmd = MoveCommand(player, new_cell)
cmd.execute()
history.append(cmd)
else:
print(" Стена! Нельзя пройти.")
if __name__ == "__main__":
main()