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[ ]:
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|