forked from UNN/2026-rff_mp
216 lines
6.1 KiB
Python
216 lines
6.1 KiB
Python
#!/usr/bin/env python
|
||
# coding: utf-8
|
||
|
||
# In[7]:
|
||
|
||
|
||
import sys
|
||
import os
|
||
|
||
# Добавляем текущую папку в путь
|
||
sys.path.insert(0, os.getcwd())
|
||
|
||
# Импорты с вашими именами файлов
|
||
from modelsMaze import Maze, Cell
|
||
from buildersText_maze_builder import TextFieldMazeBuilder
|
||
from strategiesBfs_strategy import BFSStrategy
|
||
from strategiesDfs_strategy import DFSStrategy
|
||
from strategiesA_star_strategy import AStarStrategy
|
||
from solverMaze_solver import MazeSolver
|
||
from visualizationConsole_view import ConsoleView
|
||
from commandsPlayer import Player
|
||
from commandsMove_command import MoveCommand
|
||
from experimentsBenchmark import Benchmark
|
||
|
||
def create_test_mazes():
|
||
"""Создать тестовые лабиринты в папке mazes/."""
|
||
mazes_dir = "mazes"
|
||
os.makedirs(mazes_dir, exist_ok=True)
|
||
|
||
# Маленький лабиринт 10×10
|
||
small = [
|
||
"##########",
|
||
"#S #",
|
||
"# ##### #",
|
||
"# # # #",
|
||
"# # # # #",
|
||
"# # # #",
|
||
"##### # #",
|
||
"# #",
|
||
"# E#",
|
||
"##########",
|
||
]
|
||
|
||
# Пустой лабиринт
|
||
empty = ["S" + " " * 48 + "E"] + [" " * 50 for _ in range(48)]
|
||
|
||
# Лабиринт без выхода
|
||
no_exit = [
|
||
"##########",
|
||
"#S #",
|
||
"# ##### #",
|
||
"# # # #",
|
||
"# # # # #",
|
||
"# # # #",
|
||
"##### # #",
|
||
"# #",
|
||
"##########",
|
||
"##########",
|
||
]
|
||
|
||
mazes = {
|
||
"small.txt": small,
|
||
"empty.txt": empty,
|
||
"no_exit.txt": no_exit,
|
||
}
|
||
|
||
for name, content in mazes.items():
|
||
path = os.path.join(mazes_dir, name)
|
||
with open(path, 'w', encoding='utf-8') as f:
|
||
f.write('\n'.join(content))
|
||
print(f"Создан тестовый лабиринт: {path}")
|
||
|
||
print()
|
||
|
||
def demo_builder_and_strategy():
|
||
"""Демонстрация паттернов Builder и Strategy."""
|
||
print("\n" + "=" * 60)
|
||
print("ДЕМОНСТРАЦИЯ ПАТТЕРНОВ BUILDER И STRATEGY")
|
||
print("=" * 60)
|
||
|
||
builder = TextFieldMazeBuilder()
|
||
maze = builder.build_from_file("mazes/small.txt")
|
||
|
||
strategies = [
|
||
BFSStrategy(),
|
||
DFSStrategy(),
|
||
AStarStrategy(),
|
||
]
|
||
|
||
for strategy in strategies:
|
||
print(f"\n--- Используем стратегию: {strategy.name} ---")
|
||
solver = MazeSolver(maze, strategy)
|
||
path = solver.solve()
|
||
|
||
if path:
|
||
print(f" Путь найден! Длина: {len(path)}")
|
||
print(f" Время: {solver.last_stats.time_ms:.2f} мс")
|
||
print(f" Посещено клеток: {solver.last_stats.visited_cells}")
|
||
else:
|
||
print(" Путь не найден!")
|
||
|
||
return maze
|
||
|
||
def demo_observer(maze: Maze):
|
||
"""Демонстрация паттерна Observer."""
|
||
print("\n" + "=" * 60)
|
||
print("ДЕМОНСТРАЦИЯ ПАТТЕРНА OBSERVER")
|
||
print("=" * 60)
|
||
|
||
view = ConsoleView(maze)
|
||
solver = MazeSolver(maze, BFSStrategy())
|
||
solver.attach(view)
|
||
|
||
print("Запускаем поиск с наблюдателем...")
|
||
path = solver.solve()
|
||
|
||
view.set_solution_path(path)
|
||
view.render()
|
||
|
||
return view
|
||
|
||
def demo_command(maze: Maze, view: ConsoleView):
|
||
"""Демонстрация паттерна Command."""
|
||
print("\n" + "=" * 60)
|
||
print("ДЕМОНСТРАЦИЯ ПАТТЕРНА COMMAND")
|
||
print("=" * 60)
|
||
|
||
player = Player(maze, maze.start_cell)
|
||
view.set_player_position(player.position)
|
||
|
||
print("Управление игроком:")
|
||
print(" W/A/S/D - движение, Z - отмена, Q - выход")
|
||
|
||
history = []
|
||
|
||
while True:
|
||
view.render()
|
||
|
||
cmd = input("Ваш ход: ").strip().lower()
|
||
|
||
if cmd == 'q':
|
||
break
|
||
elif cmd == 'z':
|
||
if history:
|
||
last_cmd = history.pop()
|
||
last_cmd.undo()
|
||
view.set_player_position(player.position)
|
||
print("Последний ход отменён")
|
||
else:
|
||
print("Нечего отменять")
|
||
elif cmd in MoveCommand.DIRECTIONS:
|
||
move_cmd = MoveCommand(player, maze, cmd)
|
||
if move_cmd.execute():
|
||
history.append(move_cmd)
|
||
view.set_player_position(player.position)
|
||
|
||
if player.position == maze.exit_cell:
|
||
print("\n🎉 ПОБЕДА! ВЫ НАШЛИ ВЫХОД! 🎉")
|
||
view.render()
|
||
break
|
||
else:
|
||
print("Туда нельзя пройти")
|
||
else:
|
||
print("Неизвестная команда")
|
||
|
||
print("Игра завершена")
|
||
|
||
def run_experiments():
|
||
"""Запуск экспериментального сравнения."""
|
||
print("\n" + "=" * 60)
|
||
print("ЭКСПЕРИМЕНТАЛЬНОЕ СРАВНЕНИЕ АЛГОРИТМОВ")
|
||
print("=" * 60)
|
||
|
||
builder = TextFieldMazeBuilder()
|
||
benchmark = Benchmark()
|
||
|
||
maze_files = ["small.txt", "empty.txt", "no_exit.txt"]
|
||
|
||
for maze_file in maze_files:
|
||
try:
|
||
maze = builder.build_from_file(f"mazes/{maze_file}")
|
||
print(f"\nТестируем: {maze_file} ({maze.width}×{maze.height})")
|
||
benchmark.run_on_maze(maze, maze_file, iterations=5)
|
||
except FileNotFoundError:
|
||
print(f"Файл {maze_file} не найден")
|
||
except ValueError as e:
|
||
print(f"Ошибка: {e}")
|
||
|
||
benchmark.print_summary()
|
||
benchmark.save_to_csv()
|
||
|
||
def main():
|
||
"""Главная функция."""
|
||
print("=" * 60)
|
||
print("ПРОГРАММА ПОИСКА ВЫХОДА ИЗ ЛАБИРИНТА")
|
||
print("Паттерны: Builder, Strategy, Observer, Command")
|
||
print("=" * 60)
|
||
|
||
create_test_mazes()
|
||
maze = demo_builder_and_strategy()
|
||
view = demo_observer(maze)
|
||
demo_command(maze, view)
|
||
run_experiments()
|
||
|
||
print("\nПрограмма завершена!")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|
||
|
||
# In[ ]:
|
||
|
||
|
||
|
||
|