From e6c58ac054fdce6140d097d13650d28ee75a26e5 Mon Sep 17 00:00:00 2001 From: volkovim Date: Sun, 24 May 2026 21:48:59 +0300 Subject: [PATCH] [2] task2 --- volkovim/task2/builders/maze_builder.py | 8 + volkovim/task2/builders/text_file_builder.py | 102 ++++++++++++ volkovim/task2/command/command.py | 12 ++ volkovim/task2/command/move_command.py | 65 ++++++++ volkovim/task2/command/player.py | 13 ++ volkovim/task2/core/cell.py | 40 +++++ volkovim/task2/core/maze.py | 59 +++++++ volkovim/task2/core/search_stats.py | 22 +++ volkovim/task2/experiments/benchmark.py | 93 +++++++++++ volkovim/task2/experiments/plots.py | 161 +++++++++++++++++++ volkovim/task2/experiments/results.csv | 16 ++ volkovim/task2/main.py | 70 ++++++++ volkovim/task2/mazes/blocked.txt | 3 + volkovim/task2/mazes/empty.txt | 5 + volkovim/task2/mazes/large.txt | 100 ++++++++++++ volkovim/task2/mazes/medium.txt | 50 ++++++ volkovim/task2/mazes/small.txt | 10 ++ volkovim/task2/observer/console_view.py | 64 ++++++++ volkovim/task2/observer/observer.py | 8 + volkovim/task2/report/report_2.docx | Bin 0 -> 126126 bytes volkovim/task2/requirements.txt | 0 volkovim/task2/solver/maze_solver.py | 73 +++++++++ volkovim/task2/solver/search_stats.py | 22 +++ volkovim/task2/strategies/astar.py | 107 ++++++++++++ volkovim/task2/strategies/bfs.py | 51 ++++++ volkovim/task2/strategies/dfs.py | 52 ++++++ volkovim/task2/strategies/dijkstra.py | 0 volkovim/task2/strategies/strategy.py | 8 + 28 files changed, 1214 insertions(+) create mode 100644 volkovim/task2/builders/maze_builder.py create mode 100644 volkovim/task2/builders/text_file_builder.py create mode 100644 volkovim/task2/command/command.py create mode 100644 volkovim/task2/command/move_command.py create mode 100644 volkovim/task2/command/player.py create mode 100644 volkovim/task2/core/cell.py create mode 100644 volkovim/task2/core/maze.py create mode 100644 volkovim/task2/core/search_stats.py create mode 100644 volkovim/task2/experiments/benchmark.py create mode 100644 volkovim/task2/experiments/plots.py create mode 100644 volkovim/task2/experiments/results.csv create mode 100644 volkovim/task2/main.py create mode 100644 volkovim/task2/mazes/blocked.txt create mode 100644 volkovim/task2/mazes/empty.txt create mode 100644 volkovim/task2/mazes/large.txt create mode 100644 volkovim/task2/mazes/medium.txt create mode 100644 volkovim/task2/mazes/small.txt create mode 100644 volkovim/task2/observer/console_view.py create mode 100644 volkovim/task2/observer/observer.py create mode 100644 volkovim/task2/report/report_2.docx create mode 100644 volkovim/task2/requirements.txt create mode 100644 volkovim/task2/solver/maze_solver.py create mode 100644 volkovim/task2/solver/search_stats.py create mode 100644 volkovim/task2/strategies/astar.py create mode 100644 volkovim/task2/strategies/bfs.py create mode 100644 volkovim/task2/strategies/dfs.py create mode 100644 volkovim/task2/strategies/dijkstra.py create mode 100644 volkovim/task2/strategies/strategy.py diff --git a/volkovim/task2/builders/maze_builder.py b/volkovim/task2/builders/maze_builder.py new file mode 100644 index 0000000..b5894f4 --- /dev/null +++ b/volkovim/task2/builders/maze_builder.py @@ -0,0 +1,8 @@ +from abc import ABC, abstractmethod + + +class MazeBuilder(ABC): + + @abstractmethod + def buildFromFile(self, filename): + pass \ No newline at end of file diff --git a/volkovim/task2/builders/text_file_builder.py b/volkovim/task2/builders/text_file_builder.py new file mode 100644 index 0000000..91f6823 --- /dev/null +++ b/volkovim/task2/builders/text_file_builder.py @@ -0,0 +1,102 @@ +from builders.maze_builder import MazeBuilder +from core.cell import Cell +from core.maze import Maze + + +class TextFileMazeBuilder(MazeBuilder): + + def buildFromFile(self, filename): + + with open(filename, "r", encoding="utf-8") as source: + raw_lines = [line.rstrip("\n") for line in source] + + if not raw_lines: + raise ValueError("Maze file is empty") + + expected_width = len(raw_lines[0]) + + blueprint = [] + start_cell = None + exit_cell = None + + for y_index, raw in enumerate(raw_lines): + + if len(raw) != expected_width: + raise ValueError( + f"Broken maze shape at line {y_index + 1}" + ) + + row_pack = [] + + for x_index, symbol in enumerate(raw): + + current = None + + if symbol == "#": + current = Cell( + x_index, + y_index, + isWall=True + ) + + elif symbol == " ": + current = Cell( + x_index, + y_index + ) + + elif symbol == "S": + + if start_cell: + raise ValueError( + "Multiple start cells detected" + ) + + current = Cell( + x_index, + y_index, + isStart=True + ) + + start_cell = current + + elif symbol == "E": + + if exit_cell: + raise ValueError( + "Multiple exit cells detected" + ) + + current = Cell( + x_index, + y_index, + isExit=True + ) + + exit_cell = current + + else: + raise ValueError( + f"Unsupported symbol '{symbol}' " + f"at ({x_index}, {y_index})" + ) + + row_pack.append(current) + + blueprint.append(row_pack) + + if start_cell is None: + raise ValueError( + "Start cell S not found" + ) + + if exit_cell is None: + raise ValueError( + "Exit cell E not found" + ) + + return Maze( + blueprint, + start_cell=start_cell, + exit_cell=exit_cell + ) \ No newline at end of file diff --git a/volkovim/task2/command/command.py b/volkovim/task2/command/command.py new file mode 100644 index 0000000..9dbbf3f --- /dev/null +++ b/volkovim/task2/command/command.py @@ -0,0 +1,12 @@ +from abc import ABC, abstractmethod + + +class Command(ABC): + + @abstractmethod + def execute(self): + pass + + @abstractmethod + def undo(self): + pass \ No newline at end of file diff --git a/volkovim/task2/command/move_command.py b/volkovim/task2/command/move_command.py new file mode 100644 index 0000000..6f96288 --- /dev/null +++ b/volkovim/task2/command/move_command.py @@ -0,0 +1,65 @@ +from command.command import Command + + +class MoveCommand(Command): + + def __init__( + self, + player, + maze, + direction + ): + self.player = player + self.maze = maze + self.direction = direction + self.previous = None + + def _targetCell(self): + + offsets = { + "W": (0, -1), + "S": (0, 1), + "A": (-1, 0), + "D": (1, 0) + } + + dx, dy = offsets.get( + self.direction.upper(), + (0, 0) + ) + + x, y = self.player.getPosition() + + return self.maze.getCell( + x + dx, + y + dy + ) + + def execute(self): + + destination = self._targetCell() + + if destination is None: + return False + + if not destination.isPassable(): + return False + + self.previous = self.player.current + + self.player.place( + destination + ) + + return True + + def undo(self): + + if self.previous is None: + return False + + self.player.place( + self.previous + ) + + return True \ No newline at end of file diff --git a/volkovim/task2/command/player.py b/volkovim/task2/command/player.py new file mode 100644 index 0000000..9f8249b --- /dev/null +++ b/volkovim/task2/command/player.py @@ -0,0 +1,13 @@ +class Player: + def __init__(self, start_cell): + self.current = start_cell + + def place(self, cell): + self.current = cell + + def getPosition(self): + return self.current.getPosition() + + def __str__(self): + x, y = self.getPosition() + return f"Player({x}, {y})" \ No newline at end of file diff --git a/volkovim/task2/core/cell.py b/volkovim/task2/core/cell.py new file mode 100644 index 0000000..d642eda --- /dev/null +++ b/volkovim/task2/core/cell.py @@ -0,0 +1,40 @@ +class Cell: + def __init__( + self, + x: int, + y: int, + isWall: bool = False, + isStart: bool = False, + isExit: bool = False + ): + self.x = x + self.y = y + self.isWall = isWall + self.isStart = isStart + self.isExit = isExit + + def isPassable(self) -> bool: + return self.isWall is False + + def getPosition(self): + return self.x, self.y + + def __str__(self): + if self.isStart: + return "S" + + if self.isExit: + return "E" + + if self.isWall: + return "#" + + return " " + + def __repr__(self): + return ( + f"Cell(x={self.x}, y={self.y}, " + f"wall={self.isWall}, " + f"start={self.isStart}, " + f"exit={self.isExit})" + ) \ No newline at end of file diff --git a/volkovim/task2/core/maze.py b/volkovim/task2/core/maze.py new file mode 100644 index 0000000..6a60931 --- /dev/null +++ b/volkovim/task2/core/maze.py @@ -0,0 +1,59 @@ +from core.cell import Cell + + +class Maze: + def __init__(self, cells_map, start_cell=None, exit_cell=None): + self.cells = cells_map + self.start = start_cell + self.exit = exit_cell + + self.height = len(cells_map) + self.width = len(cells_map[0]) if self.height else 0 + + def getCell(self, x: int, y: int): + if y < 0 or y >= self.height: + return None + + if x < 0 or x >= self.width: + return None + + return self.cells[y][x] + + def getNeighbors(self, current: Cell): + reachable = [] + + top = self.getCell(current.x, current.y - 1) + right = self.getCell(current.x + 1, current.y) + bottom = self.getCell(current.x, current.y + 1) + left = self.getCell(current.x - 1, current.y) + + for candidate in (top, right, bottom, left): + if candidate is None: + continue + + if candidate.isPassable(): + reachable.append(candidate) + + return reachable + + def hasStart(self): + return self.start is not None + + def hasExit(self): + return self.exit is not None + + def size(self): + return self.width, self.height + + def __str__(self): + rows = [] + + for line in self.cells: + visual = "" + + for cell in line: + visual += str(cell) + + rows.append(visual) + + return "\n".join(rows) \ No newline at end of file diff --git a/volkovim/task2/core/search_stats.py b/volkovim/task2/core/search_stats.py new file mode 100644 index 0000000..9407acb --- /dev/null +++ b/volkovim/task2/core/search_stats.py @@ -0,0 +1,22 @@ +class SearchStats: + def __init__( + self, + strategy_name, + elapsed_ms, + visited_cells, + path_length + ): + self.strategy_name = strategy_name + self.elapsed_ms = elapsed_ms + self.visited_cells = visited_cells + self.path_length = path_length + + def __str__(self): + lines = [ + f"Strategy: {self.strategy_name}", + f"Time: {self.elapsed_ms:.3f} ms", + f"Visited: {self.visited_cells}", + f"Path length: {self.path_length}" + ] + + return "\n".join(lines) \ No newline at end of file diff --git a/volkovim/task2/experiments/benchmark.py b/volkovim/task2/experiments/benchmark.py new file mode 100644 index 0000000..e563600 --- /dev/null +++ b/volkovim/task2/experiments/benchmark.py @@ -0,0 +1,93 @@ +import csv + +from solver.maze_solver import MazeSolver + + +class BenchmarkRunner: + + def __init__( + self, + maze, + strategies, + cycles=5 + ): + self.maze = maze + self.strategies = strategies + self.cycles = cycles + + def launch(self): + + report = [] + + for strategy in self.strategies: + + solver = MazeSolver( + self.maze, + strategy + ) + + total_time = 0 + total_visited = 0 + total_path = 0 + + for _ in range(self.cycles): + + _, stats = solver.solve() + + total_time += stats.time_ms + total_visited += stats.visited_cells + total_path += stats.path_length + + report.append( + { + "maze": "", + "strategy": + strategy.__class__.__name__, + "time_ms": + round( + total_time / self.cycles, + 4 + ), + "visited_cells": + round( + total_visited / self.cycles, + 2 + ), + "path_length": + round( + total_path / self.cycles, + 2 + ) + } + ) + + return report + + def exportCSV( + self, + filename, + results + ): + + with open( + filename, + "w", + newline="", + encoding="utf-8" + ) as file: + + writer = csv.DictWriter( + file, + fieldnames=[ + "maze", + "strategy", + "time_ms", + "visited_cells", + "path_length" + ] + ) + + writer.writeheader() + + for row in results: + writer.writerow(row) \ No newline at end of file diff --git a/volkovim/task2/experiments/plots.py b/volkovim/task2/experiments/plots.py new file mode 100644 index 0000000..b0da4d2 --- /dev/null +++ b/volkovim/task2/experiments/plots.py @@ -0,0 +1,161 @@ +import csv +import matplotlib.pyplot as plt + + +class ChartBuilder: + + def __init__( + self, + csv_file + ): + self.csv_file = csv_file + + def _read(self): + + rows = [] + + with open( + self.csv_file, + "r", + encoding="utf-8" + ) as file: + + reader = csv.DictReader(file) + + for row in reader: + rows.append(row) + + return rows + + def buildTimeChart(self): + + rows = self._read() + + labels = [] + values = [] + + for row in rows: + + labels.append( + f"{row['maze']}\n" + f"{row['strategy']}" + ) + + values.append( + float( + row["time_ms"] + ) + ) + + plt.figure() + + plt.bar( + labels, + values + ) + + plt.title( + "Search Time" + ) + + plt.ylabel( + "Milliseconds" + ) + + plt.xticks( + rotation=45 + ) + + plt.tight_layout() + + plt.show() + + def buildVisitedChart(self): + + rows = self._read() + + labels = [] + values = [] + + for row in rows: + + labels.append( + f"{row['maze']}\n" + f"{row['strategy']}" + ) + + values.append( + float( + row[ + "visited_cells" + ] + ) + ) + + plt.figure() + + plt.bar( + labels, + values + ) + + plt.title( + "Visited Cells" + ) + + plt.ylabel( + "Cells" + ) + + plt.xticks( + rotation=45 + ) + + plt.tight_layout() + + plt.show() + + def buildPathChart(self): + + rows = self._read() + + labels = [] + values = [] + + for row in rows: + + labels.append( + f"{row['maze']}\n" + f"{row['strategy']}" + ) + + values.append( + float( + row[ + "path_length" + ] + ) + ) + + plt.figure() + + plt.bar( + labels, + values + ) + + plt.title( + "Path Length" + ) + + plt.ylabel( + "Cells" + ) + + plt.xticks( + rotation=45 + ) + + plt.tight_layout() + + plt.show() \ No newline at end of file diff --git a/volkovim/task2/experiments/results.csv b/volkovim/task2/experiments/results.csv new file mode 100644 index 0000000..230672b --- /dev/null +++ b/volkovim/task2/experiments/results.csv @@ -0,0 +1,16 @@ +maze,strategy,time_ms,visited_cells,path_length +small.txt,BFSStrategy,0.0676,53.0,23.0 +small.txt,DFSStrategy,0.0527,31.0,31.0 +small.txt,AStarStrategy,0.0682,46.0,23.0 +medium.txt,BFSStrategy,0.7144,717.0,431.0 +medium.txt,DFSStrategy,0.6878,737.0,431.0 +medium.txt,AStarStrategy,0.6968,591.0,431.0 +large.txt,BFSStrategy,2.103,2491.0,1171.0 +large.txt,DFSStrategy,2.7719,3019.0,1243.0 +large.txt,AStarStrategy,2.5953,1995.0,1171.0 +empty.txt,BFSStrategy,0.027,19.0,8.0 +empty.txt,DFSStrategy,0.0115,8.0,8.0 +empty.txt,AStarStrategy,0.0151,8.0,8.0 +blocked.txt,BFSStrategy,0.002,1.0,0.0 +blocked.txt,DFSStrategy,0.0013,1.0,0.0 +blocked.txt,AStarStrategy,0.0019,1.0,0.0 diff --git a/volkovim/task2/main.py b/volkovim/task2/main.py new file mode 100644 index 0000000..8f7bb39 --- /dev/null +++ b/volkovim/task2/main.py @@ -0,0 +1,70 @@ +from builders.text_file_builder import TextFileMazeBuilder + +from strategies.bfs import BFSStrategy +from strategies.dfs import DFSStrategy +from strategies.astar import AStarStrategy + +from experiments.benchmark import BenchmarkRunner +from experiments.plots import ChartBuilder + + +builder = TextFileMazeBuilder() + +maze_files = [ + "small.txt", + "medium.txt", + "large.txt", + "empty.txt", + "blocked.txt" +] + +all_results = [] + +for maze_file in maze_files: + + print() + print("Loading:", maze_file) + + maze = builder.buildFromFile( + f"mazes/{maze_file}" + ) + + runner = BenchmarkRunner( + maze, + [ + BFSStrategy(), + DFSStrategy(), + AStarStrategy() + ], + cycles=10 + ) + + results = runner.launch() + + for row in results: + row["maze"] = maze_file + + all_results.extend(results) + +runner.exportCSV( + "experiments/results.csv", + all_results +) + +print() +print("CSV created") + +charts = ChartBuilder( + "experiments/results.csv" +) + +print("Time chart...") +charts.buildTimeChart() + +print("Visited chart...") +charts.buildVisitedChart() + +print("Path chart...") +charts.buildPathChart() + +print("Done") \ No newline at end of file diff --git a/volkovim/task2/mazes/blocked.txt b/volkovim/task2/mazes/blocked.txt new file mode 100644 index 0000000..179e497 --- /dev/null +++ b/volkovim/task2/mazes/blocked.txt @@ -0,0 +1,3 @@ +########## +#S#####E## +########## \ No newline at end of file diff --git a/volkovim/task2/mazes/empty.txt b/volkovim/task2/mazes/empty.txt new file mode 100644 index 0000000..d502d43 --- /dev/null +++ b/volkovim/task2/mazes/empty.txt @@ -0,0 +1,5 @@ +########## +#S E# +# # +# # +########## \ No newline at end of file diff --git a/volkovim/task2/mazes/large.txt b/volkovim/task2/mazes/large.txt new file mode 100644 index 0000000..0ce5102 --- /dev/null +++ b/volkovim/task2/mazes/large.txt @@ -0,0 +1,100 @@ +S # # # # # # # # # # # # # # + # # ####### ### # ##### # # # # # # # # ### # # ### # # ### # ##### # ##### ### ### ### ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### ### ### ##### ##### ####### # ##### ####### # # # ####### ##### # ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ##### # # ##### # # ####### # ### ##### # # # # ### ### ######### ##### # ##### # # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ### ### ####### # # ### ######### ### ### ### ### # # # # # ### ##### # # ### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ##### ##### ######### ######### # ##### ### # ####### # ##### ### ####### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # + # ################# # ### # # # # # ########### ############# # ##### ##### ##### # ##### ### # ### + # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ### ####### # ##### ######### ### # ### ### # ####### # ### ####### ##### # ### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ######### ### ### # ### # ####### ##### # # # ####### ##### ####### # ########### ####### ######### + # # # # # # # # # # # # # # # # # # # # # +## # ####### ### ##### # ####### ### # # # # ##### ### ########### # # # ### # ##### # # ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # ########### ######### # ### # # ### ### ####### ### # # # # ##### # ### ##### # # ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ##### # # # # # ### # ### ##### # # # ##### # ### # ### # # # # # # # ##### ### ####### # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### ### # # # # # ######### ### ### ### # ##### ##### ### # ##### # ######### ############# ### # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### # # ### ### ##### # ### ### ##### # # ### # ##### ##### ### ### # ##### ### # # ### # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### ####### ### ### ######### ### # # ##### # ### ########### ### # ### ####### ### # # # + # # # # # # # # # # # # # # # # # # # # # # + ################### # # # # ### # # # ######### # # ### ############### # ### ##### ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # # ### # ####### # # ##### # # ### ##### # ####### # # # ######### # ######### ##### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +#### # # ### # # ### # ### ####### ##### # # ### # # ##### # # ####### # # # ##### ### # # ####### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ### ### # ### ### # # # ### # ####### ### # ########### # ##### ##### # # ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ########### # # ########### ### # # # # # ### # # ### # ####### # ######### # # ### # ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # +######## # # # ### # ########### # # ####### ### # # # ####### ### # # # ### # ### ######### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ##### ##### ### # # # ####### ### ### # # # # ############# # ##### # ### ##### ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # ### # ##### # # # ### # # # ### # ### ### # # # # ########### ####### # ##### ####### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ####### # ##### # ### ### # # # # # # # ####### ### # # # # # # # # ### # # ##### # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # # ##### ####### # ### # ### ### ####### # # ### ####### ### ####### # ### ####### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### # # ### ### # ######### ### ### ### ### ####### ##### # ######### ##### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ####### # ##### ### # # # # # ### ### # ### ### ######### # ####### # ####### ### ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### # ### ### # # # # # # ####### ##### ### # # ##### # ### # # ####### # # # ### # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ######### # # ####### ### ### # ##### ######### # # # ####### ### # # # # ### # + # # # # # # # # # # # # # # # # # # # # # # # + ### ######### ####### # # ######### # # ### ### ### ##### ### # ########### ######### # # # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # +## ######### # ### # ####### ### # ### ### # # ####### # ### ##### ### # # ### # ### ##### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # ### ### ### # # # ##### # ### # ### ### # # # ####### ##### ### ### # ##### # ##### # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ### ### # ### # ######### # ######### # ### # # # ### ##### ### # ### # # ### # ##### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### ##### ####### ### # ##### # # # ### ### # ##### # # ### # ####### ##### # # # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### ######### # ##### ### # ### # # # ############# ### ### # ##### # ### ######### # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ##### # ### ### # # # ### # # ######### # # ##### ### ####### ### # ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + # ############### ### ####### ### # ### ####### # # # # ######### # ### # # # ##### ##### # # ##### + # # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # ### ######### # ######### # # ### # # ####### # ########### # # # ##### ####### # # + # # # # # # # # # # # # # # # # # # # # # # # +## # ####### ### # # # ############# ### ### ### ### ##### # # ### ########### ##### # ### ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # # # ##### ### # # ##### ####### # # ### ### # # ##### # # ####### ##### # # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +###### ##### ### # ### ### # # ########### # # # ##### # ### ##### # # ### ######### ### ##### # ### + # # # # # # # # # # # # # # # # # # # # # # # + # # # # # ### ####### ######### # # ######### ### # ##### ##### ##### ### # # # # # # ### ####### # + # # # # # # # # # # # # # # # # # # # # # # # # +#### # ##### # # # ##### ### # ### # ##### ### # ##### ### ######### ### ### ########### # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### ##### # ####### # # # ##### # ### # # # # ####### ##### # # ### ### # # # # ### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ### # ##### # # # ############### ### ######### ### # ##### # # ######### # ### # ### # # # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### # ### # ##### ##### # # ### # ### # # ##### # ### # # # ####### # ##### # # # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### # # # ##### ##### # # # ### ### # # # # ######### # ########### # # ##### ####### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ##### # ### ####### ########### ### # # ####### # # ##### # # # ### ##### ##### # ##### # + # # # # # # # # # # # # # # # # # # # # # # + ### ##### ########### # ### # # ####### # # # ############# # ### ### # ### ######### # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ##### ####### # ### # # ##### # ### ####### ######### # ########### ### # ######### # # + # # # # # # # # # +################################################################################################## E \ No newline at end of file diff --git a/volkovim/task2/mazes/medium.txt b/volkovim/task2/mazes/medium.txt new file mode 100644 index 0000000..6eba40a --- /dev/null +++ b/volkovim/task2/mazes/medium.txt @@ -0,0 +1,50 @@ +S # # # # + ####### ### # # ########### ##### # ##### ##### # + # # # # # # # # # # +## # # ### ####### ##### ####### # ### ######### # + # # # # # # # # # # # # # + ####### # # # # ### ##### # ### ### # # # # ### # + # # # # # # # # # # # # # # # # # + # ### # ### # ### ### # # ### ### ####### # # ### + # # # # # # # # # # # # # # + # # ############# # ### ### # ######### # # ### # + # # # # # # # # # + ########### ########### # ##### ### ### # # # ### + # # # # # # # # # # # # # # + # # ####### # ### # ##### ### ### ### ### # # # # + # # # # # # # # # # # # # # # # +###### ### ### # # # # # # # ### ### ##### # # # # + # # # # # # # # # # # # # # # + ### # # ######### ### # # # # ####### ##### # # # + # # # # # # # # # # # # # # + ### ### # ##### # # ######### # # # # ##### # # # + # # # # # # # # # # # # +## # ######### # # ### ### # ### ######### ##### # + # # # # # # # # # # # # + ##### # ### # ### ##### # # # ####### ##### # # # + # # # # # # # # # # # # # # # +## # ##### # # ##### ##### ### ### # ### # # # ### + # # # # # # # # # # # # # + ##### # ### # # ##### ### # ### ######### # ##### + # # # # # # # # # # # + # ####### ######### ### ####### # # ####### ### # + # # # # # # # # # # # # # # + # # ####### # # ##### # # ### ### # # # # ##### # + # # # # # # # # # # # # # # # # + # ##### # ####### # # # # # ### # ### # # # ### # + # # # # # # # # # # # # # # # + # ########### # ### ####### ### # ### # # # # # # + # # # # # # # # # # # # # + # # ####### ##### ########### ##### # # ##### # # + # # # # # # # # # # # + ### ### ### # ############### # # # ##### ### ### + # # # # # # # # # # # # # # + # ### ### # ### ##### # # # # # ##### # ### # # # + # # # # # # # # # # # # # # + # # ####### # ### ######### ######### ### # # # # + # # # # # # # # # # # # # # # + ##### # ####### # # # ### # # # # # ### ### # # # + # # # # # # # # # # # # # # # +## ### ##### ####### ### # # ### ##### # ### ### # + # # # # +################################################ E \ No newline at end of file diff --git a/volkovim/task2/mazes/small.txt b/volkovim/task2/mazes/small.txt new file mode 100644 index 0000000..439365c --- /dev/null +++ b/volkovim/task2/mazes/small.txt @@ -0,0 +1,10 @@ +S # + ### ### # + # # # +## # # ### + # # # + ####### # + # # +## # ##### + +######## E \ No newline at end of file diff --git a/volkovim/task2/observer/console_view.py b/volkovim/task2/observer/console_view.py new file mode 100644 index 0000000..05f31fc --- /dev/null +++ b/volkovim/task2/observer/console_view.py @@ -0,0 +1,64 @@ +from observer.observer import Observer + + +class ConsoleView(Observer): + + def update(self, event): + + event_type = event.get("type") + + if event_type == "maze_loaded": + print("[VIEW] Maze loaded") + + elif event_type == "search_started": + print("[VIEW] Search started") + + elif event_type == "search_finished": + print("[VIEW] Search completed") + + elif event_type == "path_found": + print( + f"[VIEW] Path length: " + f"{event.get('length')}" + ) + + def render( + self, + maze, + path=None + ): + route_marks = set() + + if path: + for cell in path: + route_marks.add( + cell.getPosition() + ) + + screen = [] + + for row in maze.cells: + + visual_row = "" + + for cell in row: + + position = cell.getPosition() + + if ( + position in route_marks + and not cell.isStart + and not cell.isExit + ): + visual_row += "*" + + else: + visual_row += str(cell) + + screen.append( + visual_row + ) + + print( + "\n".join(screen) + ) \ No newline at end of file diff --git a/volkovim/task2/observer/observer.py b/volkovim/task2/observer/observer.py new file mode 100644 index 0000000..3a8886f --- /dev/null +++ b/volkovim/task2/observer/observer.py @@ -0,0 +1,8 @@ +from abc import ABC, abstractmethod + + +class Observer(ABC): + + @abstractmethod + def update(self, event): + pass \ No newline at end of file diff --git a/volkovim/task2/report/report_2.docx b/volkovim/task2/report/report_2.docx new file mode 100644 index 0000000000000000000000000000000000000000..1143cd7601c18256407683097ed246eb363a90c8 GIT binary patch literal 126126 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 |x*{zT%=lEwBk8R$iJU-u>Im=r!| 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 literal 0 HcmV?d00001 diff --git a/volkovim/task2/requirements.txt b/volkovim/task2/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/volkovim/task2/solver/maze_solver.py b/volkovim/task2/solver/maze_solver.py new file mode 100644 index 0000000..cbee4ca --- /dev/null +++ b/volkovim/task2/solver/maze_solver.py @@ -0,0 +1,73 @@ +import time + +from solver.search_stats import SearchStats + + +class MazeSolver: + + def __init__( + self, + maze, + strategy + ): + self.maze = maze + self.strategy = strategy + self.observers = [] + + def addObserver( + self, + observer + ): + self.observers.append( + observer + ) + + def notify( + self, + event + ): + for observer in self.observers: + observer.update(event) + + def setStrategy( + self, + strategy + ): + self.strategy = strategy + + def solve(self): + + self.notify( + "search_started" + ) + + start_time = time.perf_counter() + + path, visited_cells = ( + self.strategy.findPath( + self.maze, + self.maze.start, + self.maze.exit + ) + ) + + finish_time = ( + time.perf_counter() + ) + + elapsed_ms = ( + finish_time + - start_time + ) * 1000 + + stats = SearchStats( + elapsed_ms, + visited_cells, + len(path) + ) + + self.notify( + "search_finished" + ) + + return path, stats \ No newline at end of file diff --git a/volkovim/task2/solver/search_stats.py b/volkovim/task2/solver/search_stats.py new file mode 100644 index 0000000..9553063 --- /dev/null +++ b/volkovim/task2/solver/search_stats.py @@ -0,0 +1,22 @@ +class SearchStats: + + def __init__( + self, + time_ms, + visited_cells, + path_length + ): + self.time_ms = time_ms + self.visited_cells = visited_cells + self.path_length = path_length + + def __str__(self): + + return ( + f"Time: " + f"{self.time_ms:.4f} ms | " + f"Visited: " + f"{self.visited_cells} | " + f"Path length: " + f"{self.path_length}" + ) \ No newline at end of file diff --git a/volkovim/task2/strategies/astar.py b/volkovim/task2/strategies/astar.py new file mode 100644 index 0000000..0907a75 --- /dev/null +++ b/volkovim/task2/strategies/astar.py @@ -0,0 +1,107 @@ +import heapq +from itertools import count +from strategies.strategy import PathFindingStrategy + + +class AStarStrategy(PathFindingStrategy): + + def _estimate(self, current, target): + return ( + abs(current.x - target.x) + + abs(current.y - target.y) + ) + + def findPath(self, maze, start, exit): + + frontier = [] + + sequence = count() + + heapq.heappush( + frontier, + ( + self._estimate(start, exit), + next(sequence), + 0, + start + ) + ) + + ancestry = {} + + travel_cost = { + start.getPosition(): 0 + } + + explored = set() + + explored_count = 0 + + while frontier: + + _, _, spent, current = heapq.heappop( + frontier + ) + + current_mark = current.getPosition() + + if current_mark in explored: + continue + + explored.add(current_mark) + explored_count += 1 + + if current == exit: + break + + for neighbor in maze.getNeighbors(current): + + mark = neighbor.getPosition() + + new_cost = spent + 1 + + if ( + mark not in travel_cost + or new_cost < travel_cost[mark] + ): + + travel_cost[mark] = new_cost + ancestry[mark] = current + + priority = ( + new_cost + + self._estimate( + neighbor, + exit + ) + ) + + heapq.heappush( + frontier, + ( + priority, + next(sequence), + new_cost, + neighbor + ) + ) + + if ( + exit.getPosition() not in ancestry + and exit != start + ): + return [], explored_count + + route = [] + cursor = exit + + while cursor != start: + route.append(cursor) + cursor = ancestry[ + cursor.getPosition() + ] + + route.append(start) + route.reverse() + + return route, explored_count \ No newline at end of file diff --git a/volkovim/task2/strategies/bfs.py b/volkovim/task2/strategies/bfs.py new file mode 100644 index 0000000..0860126 --- /dev/null +++ b/volkovim/task2/strategies/bfs.py @@ -0,0 +1,51 @@ +from collections import deque +from strategies.strategy import PathFindingStrategy + + +class BFSStrategy(PathFindingStrategy): + + def findPath(self, maze, start, exit): + + frontier = deque([start]) + + visited = { + start.getPosition() + } + + ancestry = {} + + explored_count = 0 + + while frontier: + + current = frontier.popleft() + explored_count += 1 + + if current == exit: + break + + for neighbor in maze.getNeighbors(current): + + mark = neighbor.getPosition() + + if mark in visited: + continue + + visited.add(mark) + ancestry[mark] = current + frontier.append(neighbor) + + if exit.getPosition() not in visited: + return [], explored_count + + route = [] + cursor = exit + + while cursor != start: + route.append(cursor) + cursor = ancestry[cursor.getPosition()] + + route.append(start) + route.reverse() + + return route, explored_count \ No newline at end of file diff --git a/volkovim/task2/strategies/dfs.py b/volkovim/task2/strategies/dfs.py new file mode 100644 index 0000000..3b12bdb --- /dev/null +++ b/volkovim/task2/strategies/dfs.py @@ -0,0 +1,52 @@ +from strategies.strategy import PathFindingStrategy + + +class DFSStrategy(PathFindingStrategy): + + def findPath(self, maze, start, exit): + + frontier = [start] + + visited = { + start.getPosition() + } + + ancestry = {} + + explored_count = 0 + + while frontier: + + current = frontier.pop() + explored_count += 1 + + if current == exit: + break + + neighbors = maze.getNeighbors(current) + + for neighbor in reversed(neighbors): + + point = neighbor.getPosition() + + if point in visited: + continue + + visited.add(point) + ancestry[point] = current + frontier.append(neighbor) + + if exit.getPosition() not in visited: + return [], explored_count + + route = [] + cursor = exit + + while cursor != start: + route.append(cursor) + cursor = ancestry[cursor.getPosition()] + + route.append(start) + route.reverse() + + return route, explored_count \ No newline at end of file diff --git a/volkovim/task2/strategies/dijkstra.py b/volkovim/task2/strategies/dijkstra.py new file mode 100644 index 0000000..e69de29 diff --git a/volkovim/task2/strategies/strategy.py b/volkovim/task2/strategies/strategy.py new file mode 100644 index 0000000..ef3376e --- /dev/null +++ b/volkovim/task2/strategies/strategy.py @@ -0,0 +1,8 @@ +from abc import ABC, abstractmethod + + +class PathFindingStrategy(ABC): + + @abstractmethod + def findPath(self, maze, start, exit): + pass \ No newline at end of file -- 2.43.0