From c1086c89c35c80a0e608f2915c626b949705c342 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:11:03 +0300 Subject: [PATCH 1/9] =?UTF-8?q?[2]=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=20=D0=BB=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D1=80=D0=B8=D0=BD=D1=82=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/maze.py | 0 raskatovia/docs/data/task2/solver.py | 0 raskatovia/docs/task2report.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 raskatovia/docs/data/task2/maze.py create mode 100644 raskatovia/docs/data/task2/solver.py create mode 100644 raskatovia/docs/task2report.md diff --git a/raskatovia/docs/data/task2/maze.py b/raskatovia/docs/data/task2/maze.py new file mode 100644 index 0000000..e69de29 diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py new file mode 100644 index 0000000..e69de29 diff --git a/raskatovia/docs/task2report.md b/raskatovia/docs/task2report.md new file mode 100644 index 0000000..e69de29 From a912487cdc6fac46e5a02e0ce5fb81bd6b654ae7 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:24:59 +0300 Subject: [PATCH 2/9] =?UTF-8?q?[2]=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20=D0=BB=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/maps/simple.txt | 5 ++ raskatovia/docs/data/task2/maze.py | 96 ++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 raskatovia/docs/data/task2/maps/simple.txt diff --git a/raskatovia/docs/data/task2/maps/simple.txt b/raskatovia/docs/data/task2/maps/simple.txt new file mode 100644 index 0000000..fe2e907 --- /dev/null +++ b/raskatovia/docs/data/task2/maps/simple.txt @@ -0,0 +1,5 @@ +####### +#S...F# +#.###.# +#.....# +####### \ No newline at end of file diff --git a/raskatovia/docs/data/task2/maze.py b/raskatovia/docs/data/task2/maze.py index e69de29..da42d64 100644 --- a/raskatovia/docs/data/task2/maze.py +++ b/raskatovia/docs/data/task2/maze.py @@ -0,0 +1,96 @@ +class Cell: + def __init__(self, row, col, value): + self.row = row + self.col = col + self.value = value + + def is_wall(self): + return self.value == "#" + + def is_start(self): + return self.value == "S" + + def is_finish(self): + return self.value == "F" + + +class Maze: + def __init__(self, cells, start, finish): + self.cells = cells + self.start = start + self.finish = finish + self.height = len(cells) + self.width = len(cells[0]) if cells else 0 + + def inside(self, row, col): + return 0 <= row < self.height and 0 <= col < self.width + + def get_cell(self, row, col): + if not self.inside(row, col): + return None + return self.cells[row][col] + + def is_free(self, row, col): + cell = self.get_cell(row, col) + return cell is not None and not cell.is_wall() + + def neighbors(self, row, col): + variants = [ + (row - 1, col), + (row + 1, col), + (row, col - 1), + (row, col + 1) + ] + result = [] + for next_row, next_col in variants: + if self.is_free(next_row, next_col): + result.append((next_row, next_col)) + return result + + def draw(self, path=None): + path_set = set(path) if path else set() + lines = [] + for row in range(self.height): + line = "" + for col in range(self.width): + cell = self.cells[row][col] + if (row, col) in path_set and not cell.is_start() and not cell.is_finish(): + line += "*" + else: + line += cell.value + lines.append(line) + return "\n".join(lines) + + +class MazeBuilder: + def __init__(self): + self.lines = [] + + def from_file(self, filename): + with open(filename, "r", encoding="utf-8") as file: + self.lines = [line.rstrip("\n") for line in file if line.strip()] + return self + + def build(self): + cells = [] + start = None + finish = None + width = len(self.lines[0]) + + for row, line in enumerate(self.lines): + if len(line) != width: + raise ValueError("maze lines have different length") + cell_row = [] + for col, value in enumerate(line): + cell = Cell(row, col, value) + if cell.is_start(): + start = (row, col) + if cell.is_finish(): + finish = (row, col) + cell_row.append(cell) + cells.append(cell_row) + + if start is None or finish is None: + raise ValueError("maze must have start and finish") + + return Maze(cells, start, finish) \ No newline at end of file From 308ee2d7166f8dffae01102c437374aa1f02b128 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:26:10 +0300 Subject: [PATCH 3/9] =?UTF-8?q?[2]=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B2=20=D1=88=D0=B8?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/solver.py | 58 ++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index e69de29..ae1b9f4 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -0,0 +1,58 @@ +from collections import deque +from maze import MazeBuilder + +def build_path(previous, start, finish): + if finish not in previous: + return [] + path = [] + current = finish + while current != start: + path.append(current) + current = previous[current] + path.append(start) + path.reverse() + return path + +class BfsStrategy: + def solve(self, maze): + start = maze.start + finish = maze.finish + queue = deque([start]) + previous = {start: None} + visited_count = 0 + + while queue: + current = queue.popleft() + visited_count += 1 + + if current == finish: + break + + for next_cell in maze.neighbors(current[0], current[1]): + if next_cell not in previous: + previous[next_cell] = current + queue.append(next_cell) + + path = build_path(previous, start, finish) + return { + "name": "BFS", + "path": path, + "visited": visited_count, + "length": len(path) + } + +class MazeSolver: + def __init__(self, strategy): + self.strategy = strategy + + def solve(self, maze): + return self.strategy.solve(maze) + +if __name__ == "__main__": + maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() + solver = MazeSolver(BfsStrategy()) + result = solver.solve(maze) + print("algorithm:", result["name"]) + print("visited:", result["visited"]) + print("length:", result["length"]) + print(maze.draw(result["path"])) \ No newline at end of file From a339b8fb6f108ea1d992de585054909d0db51e0f Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:34:27 +0300 Subject: [PATCH 4/9] =?UTF-8?q?[2]=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=20=D0=B2=20=D0=B3=D0=BB?= =?UTF-8?q?=D1=83=D0=B1=D0=B8=D0=BD=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/solver.py | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index ae1b9f4..bad83a7 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -40,6 +40,33 @@ class BfsStrategy: "visited": visited_count, "length": len(path) } +class DfsStrategy: + def solve(self, maze): + start = maze.start + finish = maze.finish + stack = [start] + previous = {start: None} + visited_count = 0 + + while stack: + current = stack.pop() + visited_count += 1 + + if current == finish: + break + + for next_cell in maze.neighbors(current[0], current[1]): + if next_cell not in previous: + previous[next_cell] = current + stack.append(next_cell) + + path = build_path(previous, start, finish) + return { + "name": "DFS", + "path": path, + "visited": visited_count, + "length": len(path) + } class MazeSolver: def __init__(self, strategy): @@ -50,7 +77,7 @@ class MazeSolver: if __name__ == "__main__": maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() - solver = MazeSolver(BfsStrategy()) + solver = MazeSolver(DfsStrategy()) result = solver.solve(maze) print("algorithm:", result["name"]) print("visited:", result["visited"]) From f3270c41979c3fd091f3c66ee81d05112ebb12b2 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:39:47 +0300 Subject: [PATCH 5/9] =?UTF-8?q?[2]=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BD=D1=8B=D1=85=20=D1=81=D1=82=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=B3=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/solver.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index bad83a7..1f22173 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -77,9 +77,13 @@ class MazeSolver: if __name__ == "__main__": maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() - solver = MazeSolver(DfsStrategy()) - result = solver.solve(maze) - print("algorithm:", result["name"]) - print("visited:", result["visited"]) - print("length:", result["length"]) - print(maze.draw(result["path"])) \ No newline at end of file + strategies = [BfsStrategy(), DfsStrategy()] + + for strategy in strategies: + solver = MazeSolver(strategy) + result = solver.solve(maze) + print("algorithm:", result["name"]) + print("visited:", result["visited"]) + print("length:", result["length"]) + print(maze.draw(result["path"])) + print() \ No newline at end of file From fa3d95b5c07d9bb74376460a67bdd0dd94b00f13 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Fri, 22 May 2026 21:44:40 +0300 Subject: [PATCH 6/9] =?UTF-8?q?[2]=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=20astar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/solver.py | 41 +++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index 1f22173..ad20457 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -1,3 +1,7 @@ +from collections import deque +import heapq +from maze import MazeBuilder + from collections import deque from maze import MazeBuilder @@ -67,6 +71,41 @@ class DfsStrategy: "visited": visited_count, "length": len(path) } +def distance(first, second): + return abs(first[0] - second[0]) + abs(first[1] - second[1]) + +class AstarStrategy: + def solve(self, maze): + start = maze.start + finish = maze.finish + queue = [] + heapq.heappush(queue, (0, start)) + previous = {start: None} + costs = {start: 0} + visited_count = 0 + + while queue: + current = heapq.heappop(queue)[1] + visited_count += 1 + + if current == finish: + break + + for next_cell in maze.neighbors(current[0], current[1]): + new_cost = costs[current] + 1 + if next_cell not in costs or new_cost < costs[next_cell]: + costs[next_cell] = new_cost + priority = new_cost + distance(next_cell, finish) + heapq.heappush(queue, (priority, next_cell)) + previous[next_cell] = current + + path = build_path(previous, start, finish) + return { + "name": "A*", + "path": path, + "visited": visited_count, + "length": len(path) + } class MazeSolver: def __init__(self, strategy): @@ -77,7 +116,7 @@ class MazeSolver: if __name__ == "__main__": maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() - strategies = [BfsStrategy(), DfsStrategy()] + strategies = [BfsStrategy(), DfsStrategy(), AstarStrategy()] for strategy in strategies: solver = MazeSolver(strategy) From c19eb1a1f61a7da36c38974a6e34aca4440c5370 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Sat, 23 May 2026 12:11:53 +0300 Subject: [PATCH 7/9] =?UTF-8?q?[2]=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BB=D0=B0=D0=B1=D0=B8=D1=80=D0=B8=D0=BD=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/maps/hard.txt | 9 ++++++++ raskatovia/docs/data/task2/maps/medium.txt | 7 ++++++ raskatovia/docs/data/task2/solver.py | 25 ++++++++++++++-------- 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 raskatovia/docs/data/task2/maps/hard.txt create mode 100644 raskatovia/docs/data/task2/maps/medium.txt diff --git a/raskatovia/docs/data/task2/maps/hard.txt b/raskatovia/docs/data/task2/maps/hard.txt new file mode 100644 index 0000000..99fb354 --- /dev/null +++ b/raskatovia/docs/data/task2/maps/hard.txt @@ -0,0 +1,9 @@ +############### +#S....#.......# +#.###.#.#####.# +#...#.#.....#.# +###.#.#####.#.# +#...#.....#.#.# +#.#######.#.#.# +#............F# +############### \ No newline at end of file diff --git a/raskatovia/docs/data/task2/maps/medium.txt b/raskatovia/docs/data/task2/maps/medium.txt new file mode 100644 index 0000000..70ac804 --- /dev/null +++ b/raskatovia/docs/data/task2/maps/medium.txt @@ -0,0 +1,7 @@ +########### +#S..#.....# +###.#.###.# +#...#...#.# +#.#####.#.# +#.......#F# +########### \ No newline at end of file diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index ad20457..4456ec5 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -115,14 +115,21 @@ class MazeSolver: return self.strategy.solve(maze) if __name__ == "__main__": - maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() + files = [ + "simple.txt", + "medium.txt", + "hard.txt" + ] strategies = [BfsStrategy(), DfsStrategy(), AstarStrategy()] - for strategy in strategies: - solver = MazeSolver(strategy) - result = solver.solve(maze) - print("algorithm:", result["name"]) - print("visited:", result["visited"]) - print("length:", result["length"]) - print(maze.draw(result["path"])) - print() \ No newline at end of file + for filename in files: + print("map:", filename) + maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/" + filename).build() + for strategy in strategies: + solver = MazeSolver(strategy) + result = solver.solve(maze) + print("algorithm:", result["name"]) + print("visited:", result["visited"]) + print("length:", result["length"]) + print(maze.draw(result["path"])) + print() \ No newline at end of file From 5b6854061555ef434548bef3a4b62024eac0a569 Mon Sep 17 00:00:00 2001 From: raskatovia Date: Sat, 23 May 2026 12:14:08 +0300 Subject: [PATCH 8/9] =?UTF-8?q?[2]=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=80=D1=8B=20=D0=B0=D0=BB=D0=B3?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/data/task2/results.csv | 46 ++++++++++++++++++++++++++ raskatovia/docs/data/task2/zamery.py | 40 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 raskatovia/docs/data/task2/results.csv create mode 100644 raskatovia/docs/data/task2/zamery.py diff --git a/raskatovia/docs/data/task2/results.csv b/raskatovia/docs/data/task2/results.csv new file mode 100644 index 0000000..3a391b8 --- /dev/null +++ b/raskatovia/docs/data/task2/results.csv @@ -0,0 +1,46 @@ +map,algorithm,try,time,visited,length +simple.txt,BFS,1,2.6000008801929653e-05,9,5 +simple.txt,BFS,2,1.4800010831095278e-05,9,5 +simple.txt,BFS,3,1.2799995602108538e-05,9,5 +simple.txt,BFS,4,1.1600001016631722e-05,9,5 +simple.txt,BFS,5,1.1399999493733048e-05,9,5 +simple.txt,DFS,1,9.60000033956021e-06,5,5 +simple.txt,DFS,2,7.199996616691351e-06,5,5 +simple.txt,DFS,3,6.300004315562546e-06,5,5 +simple.txt,DFS,4,6.200003554113209e-06,5,5 +simple.txt,DFS,5,6.200003554113209e-06,5,5 +simple.txt,A*,1,1.4599994756281376e-05,5,5 +simple.txt,A*,2,9.499999578110874e-06,5,5 +simple.txt,A*,3,8.29999044071883e-06,5,5 +simple.txt,A*,4,8.300004992634058e-06,5,5 +simple.txt,A*,5,2.4499997380189598e-05,5,5 +medium.txt,BFS,1,4.0400002035312355e-05,29,29 +medium.txt,BFS,2,3.700000524986535e-05,29,29 +medium.txt,BFS,3,3.670000296551734e-05,29,29 +medium.txt,BFS,4,3.470000228844583e-05,29,29 +medium.txt,BFS,5,3.370000922586769e-05,29,29 +medium.txt,DFS,1,3.4199998481199145e-05,29,29 +medium.txt,DFS,2,3.369999467395246e-05,29,29 +medium.txt,DFS,3,3.329999162815511e-05,29,29 +medium.txt,DFS,4,3.309999010525644e-05,29,29 +medium.txt,DFS,5,3.300000389572233e-05,29,29 +medium.txt,A*,1,4.470000567380339e-05,29,29 +medium.txt,A*,2,4.549999721348286e-05,29,29 +medium.txt,A*,3,4.259998968336731e-05,29,29 +medium.txt,A*,4,4.260000423528254e-05,29,29 +medium.txt,A*,5,4.1799998143687844e-05,29,29 +hard.txt,BFS,1,4.680000711232424e-05,38,19 +hard.txt,BFS,2,4.390001413412392e-05,38,19 +hard.txt,BFS,3,4.4200001866556704e-05,38,19 +hard.txt,BFS,4,4.2100000428035855e-05,38,19 +hard.txt,BFS,5,4.389999958220869e-05,38,19 +hard.txt,DFS,1,2.570000651758164e-05,19,19 +hard.txt,DFS,2,2.1800005924887955e-05,19,19 +hard.txt,DFS,3,2.19999928958714e-05,19,19 +hard.txt,DFS,4,2.1799991372972727e-05,19,19 +hard.txt,DFS,5,2.1799991372972727e-05,19,19 +hard.txt,A*,1,4.149999585933983e-05,25,19 +hard.txt,A*,2,3.7699996028095484e-05,25,19 +hard.txt,A*,3,3.6999990697950125e-05,25,19 +hard.txt,A*,4,3.680000372696668e-05,25,19 +hard.txt,A*,5,3.720000677276403e-05,25,19 diff --git a/raskatovia/docs/data/task2/zamery.py b/raskatovia/docs/data/task2/zamery.py new file mode 100644 index 0000000..c6f2656 --- /dev/null +++ b/raskatovia/docs/data/task2/zamery.py @@ -0,0 +1,40 @@ +import csv +import time +from maze import MazeBuilder +from solver import BfsStrategy, DfsStrategy, AstarStrategy, MazeSolver + +MAPS = ["simple.txt", "medium.txt", "hard.txt"] +REPEATS = 5 + +def run_one(filename, strategy): + maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/" + filename).build() + solver = MazeSolver(strategy) + start = time.perf_counter() + result = solver.solve(maze) + work_time = time.perf_counter() - start + return result, work_time + +def main(): + rows = [["map", "algorithm", "try", "time", "visited", "length"]] + strategies = [BfsStrategy(), DfsStrategy(), AstarStrategy()] + + for filename in MAPS: + for strategy in strategies: + for number in range(1, REPEATS + 1): + result, work_time = run_one(filename, strategy) + rows.append([ + filename, + result["name"], + number, + work_time, + result["visited"], + result["length"] + ]) + + with open("raskatovia/docs/data/task2/results.csv", "w", newline="", encoding="utf-8") as file: + writer = csv.writer(file) + writer.writerows(rows) + + print("results saved") + +main() \ No newline at end of file From 65594bdb6e5a1da699632f17c7b1f64d1d372fbc Mon Sep 17 00:00:00 2001 From: raskatovia Date: Sat, 23 May 2026 12:34:31 +0300 Subject: [PATCH 9/9] =?UTF-8?q?[2]=20=D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=82=D1=87=D0=B5=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- raskatovia/docs/task2report.md | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/raskatovia/docs/task2report.md b/raskatovia/docs/task2report.md index e69de29..d78ae3b 100644 --- a/raskatovia/docs/task2report.md +++ b/raskatovia/docs/task2report.md @@ -0,0 +1,46 @@ +Цель работы + +В этом задании я сделал программу для поиска пути в лабиринте. Лабиринт загружается из текстового файла, после этого для него запускаются три алгоритма: BFS, DFS и A\*. Нужно было сравнить как они проходят разные карты + + + + В файле maze.py находится описание лабиринта. Cell отвечает за отдельную клетку, а Maze хранит всю карту, старт, финиш и умеет находить соседние клетки, куда можно идти. Для загрузки карты из файла сделан MazeBuilder. Он читает строки, проверяет их длину и ищет точки S и F. \[тут я столкнулся с ошибкой на hard.txt, потому что одна строка была другой длины] + + В файле solver.py находится поиск пути.MazeSolver получает стратегию поиска и запускает её. Были сделаны три стратегии: BfsStrategy, DfsStrategy и AstarStrategy. BFS идёт в ширину, DFS идёт в глубину, а A\* использует расстояние до финиша + + Сначала программа проверялась на simple.txt, потом были добавлены medium.txt и hard.txt. Для каждой карты запускались все три алгоритма. Программа выводила найденный путь, количество посещённых клеток и длину пути + + Для замеров сделан файл zamery.py. Он запускает алгоритмы по 5 раз и сохраняет результаты в results.csv + + Результаты + +simple.txt; BFS; время 0.00001532; посещено 9; длина пути 5 + +simple.txt; DFS; время 0.00000710; посещено 5; длина пути 5 + +simple.txt; A\*; время 0.00001304; посещено 5; длина пути 5 + + + +medium.txt; BFS; время 0.00003650; посещено 29; длина пути 29 + +medium.txt; DFS; время 0.00003346; посещено 29; длина пути 29 + +medium.txt; A\*; время 0.00004344; посещено 29; длина пути 29 + + + +hard.txt; BFS; время 0.00004418; посещено 38; длина пути 19 + +hard.txt; DFS; время 0.00002262; посещено 19; длина пути 19 + +hard.txt; A\*; время 0.00003804; посещено 25; длина пути 19 + + + + По результатам видно, что на простом лабиринте разница почти не важна. На medium.txt все алгоритмы прошли примерно одинаково. На hard.txt разница заметнее: BFS посетил больше всего клеток, DFS меньше всего, а A\* оказался между ними. При этом длина пути на hard.txt у всех получилась одинаковая + + Заключение + +В работе получилось сделать загрузку лабиринта из файла и несколько способов поиска пути. BFS надёжный, но может обходить больше клеток. DFS простой и иногда быстро доходит до финиша, но зависит от формы лабиринта. A\* старается идти ближе к цели, но на маленьких картах его преимущество не всегда видно.В целом задание было понятнее когда появились карты и путь стал выводиться прямо в консоли. Самая заметная проблема была с неправильной строкой в hard.txt, но после исправления все карты начали нормально запускаться +