forked from UNN/2026-rff_mp
161 lines
5.0 KiB
Python
161 lines
5.0 KiB
Python
|
|
import os
|
|||
|
|
import csv
|
|||
|
|
from datetime import datetime
|
|||
|
|
from maze_model import Maze
|
|||
|
|
from maze_builder import TextFileMazeBuilder
|
|||
|
|
from pathfinding_strategies import BFSStrategy, DFSStrategy, AStarStrategy
|
|||
|
|
from maze_solver import MazeSolver
|
|||
|
|
|
|||
|
|
|
|||
|
|
def get_maze_file():
|
|||
|
|
maze_files = [f for f in os.listdir('.') if f.endswith('.txt') and f != 'experiment_results.csv']
|
|||
|
|
|
|||
|
|
if not maze_files:
|
|||
|
|
print("\nНет файлов лабиринтов! Поместите файлы labirint1.txt и т.д. в папку.")
|
|||
|
|
exit(1)
|
|||
|
|
|
|||
|
|
print("\nДоступные файлы лабиринтов:")
|
|||
|
|
for i, f in enumerate(maze_files, 1):
|
|||
|
|
print(f" {i}. {f}")
|
|||
|
|
|
|||
|
|
while True:
|
|||
|
|
choice = input(f"\nВыберите файл (1-{len(maze_files)}): ").strip()
|
|||
|
|
try:
|
|||
|
|
idx = int(choice) - 1
|
|||
|
|
if 0 <= idx < len(maze_files):
|
|||
|
|
return maze_files[idx]
|
|||
|
|
except ValueError:
|
|||
|
|
pass
|
|||
|
|
print(f"Неверный выбор. Введите число от 1 до {len(maze_files)}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def display_maze_with_path(maze: Maze, path=None):
|
|||
|
|
print("\n+" + "-" * maze.width + "+")
|
|||
|
|
|
|||
|
|
for y in range(maze.height):
|
|||
|
|
row = "|"
|
|||
|
|
for x in range(maze.width):
|
|||
|
|
cell = maze.get_cell(x, y)
|
|||
|
|
if cell == maze.start_cell:
|
|||
|
|
row += "S"
|
|||
|
|
elif cell == maze.exit_cell:
|
|||
|
|
row += "E"
|
|||
|
|
elif path and cell in path:
|
|||
|
|
row += "."
|
|||
|
|
elif cell.is_wall:
|
|||
|
|
row += "#"
|
|||
|
|
else:
|
|||
|
|
row += " "
|
|||
|
|
row += "|"
|
|||
|
|
print(row)
|
|||
|
|
|
|||
|
|
print("+" + "-" * maze.width + "+")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def save_to_csv(maze_name: str, algorithm_name: str, time_ms: float, path_length: int, path_found: bool, maze_size: str):
|
|||
|
|
csv_filename = "experiment_results.csv"
|
|||
|
|
|
|||
|
|
file_exists = os.path.exists(csv_filename)
|
|||
|
|
|
|||
|
|
with open(csv_filename, 'a', newline='', encoding='utf-8-sig') as f:
|
|||
|
|
writer = csv.writer(f)
|
|||
|
|
|
|||
|
|
if not file_exists:
|
|||
|
|
writer.writerow(['лабиринт', 'стратегия', 'время_мс', 'длина_пути', 'путь_найден', 'размер', 'дата_время'])
|
|||
|
|
|
|||
|
|
writer.writerow([
|
|||
|
|
maze_name,
|
|||
|
|
algorithm_name,
|
|||
|
|
round(time_ms, 3),
|
|||
|
|
path_length,
|
|||
|
|
'Да' if path_found else 'Нет',
|
|||
|
|
maze_size,
|
|||
|
|
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
print(f"Результат сохранён в {csv_filename}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def print_all_results():
|
|||
|
|
csv_filename = "experiment_results.csv"
|
|||
|
|
|
|||
|
|
with open(csv_filename, 'r', encoding='utf-8-sig') as f:
|
|||
|
|
reader = csv.reader(f)
|
|||
|
|
headers = next(reader)
|
|||
|
|
print(f"{headers[0]:<25} {headers[1]:<22} {headers[2]:<10} {headers[3]:<10} {headers[4]:<8} {headers[5]:<10}")
|
|||
|
|
for row in reader:
|
|||
|
|
print(f"{row[0]:<25} {row[1]:<22} {row[2]:<10} {row[3]:<10} {row[4]:<8} {row[5]:<10}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
filename = get_maze_file()
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
builder = TextFileMazeBuilder()
|
|||
|
|
maze = builder.build_from_file(filename)
|
|||
|
|
|
|||
|
|
maze_name = filename.replace('.txt', '')
|
|||
|
|
maze_size = f"{maze.width}x{maze.height}"
|
|||
|
|
|
|||
|
|
print(f"\nЛабиринт загружен из файла: {filename}")
|
|||
|
|
print(f" Размер: {maze_size}")
|
|||
|
|
print(f" Старт: ({maze.start_cell.x}, {maze.start_cell.y})")
|
|||
|
|
print(f" Выход: ({maze.exit_cell.x}, {maze.exit_cell.y})")
|
|||
|
|
|
|||
|
|
except FileNotFoundError:
|
|||
|
|
print(f"\nФайл '{filename}' не найден!")
|
|||
|
|
return
|
|||
|
|
except ValueError as e:
|
|||
|
|
print(f"\nОшибка в файле лабиринта: {e}")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
print("\nЗагруженный лабиринт:")
|
|||
|
|
maze.display()
|
|||
|
|
|
|||
|
|
print("ВЫБОР АЛГОРИТМА ПОИСКА")
|
|||
|
|
print("1. BFS (Поиск в ширину)")
|
|||
|
|
print("2. DFS (Поиск в глубину)")
|
|||
|
|
print("3. A* (A-Star)")
|
|||
|
|
|
|||
|
|
|
|||
|
|
choice = input("\nВыберите алгоритм (1-3): ").strip()
|
|||
|
|
|
|||
|
|
|
|||
|
|
if choice == '1':
|
|||
|
|
strategy = BFSStrategy()
|
|||
|
|
elif choice == '2':
|
|||
|
|
strategy = DFSStrategy()
|
|||
|
|
elif choice == '3':
|
|||
|
|
strategy = AStarStrategy()
|
|||
|
|
else:
|
|||
|
|
print("Неверный выбор!")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
|
|||
|
|
solver = MazeSolver(maze, strategy)
|
|||
|
|
|
|||
|
|
path, stats = solver.solve_with_stats()
|
|||
|
|
|
|||
|
|
print(stats.detailed_report())
|
|||
|
|
|
|||
|
|
if path:
|
|||
|
|
print("\nЛабиринт с найденным путём (точки):")
|
|||
|
|
display_maze_with_path(maze, path)
|
|||
|
|
else:
|
|||
|
|
print("Путь не найден!")
|
|||
|
|
|
|||
|
|
# Сохраняем результат в CSV
|
|||
|
|
save_to_csv(
|
|||
|
|
maze_name=maze_name,
|
|||
|
|
algorithm_name=stats.algorithm_name,
|
|||
|
|
time_ms=stats.execution_time_ms,
|
|||
|
|
path_length=stats.path_length,
|
|||
|
|
path_found=stats.path_found,
|
|||
|
|
maze_size=maze_size
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print("\nПрограмма завершена!")
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|