forked from UNN/2026-rff_mp
Compare commits
No commits in common. "5f7e7cec65aa9bff369b821e3b51ed0656eefbc9" and "3fbb3cf061a46d44e4ad719e92950031f2465769" have entirely different histories.
5f7e7cec65
...
3fbb3cf061
File diff suppressed because it is too large
Load Diff
|
|
@ -1,221 +0,0 @@
|
|||
Лабиринт,Алгоритм,Время,Посещено клеток,Длина пути
|
||||
maze10x10,BFS,0.0744000026315916,25.0,16.0
|
||||
maze10x10,BFS,0.0757000016164965,25.0,16.0
|
||||
maze10x10,BFS,0.0727000006008893,25.0,16.0
|
||||
maze10x10,BFS,0.0742999982321634,25.0,16.0
|
||||
maze10x10,BFS,0.0537000014446675,25.0,16.0
|
||||
maze10x10,BFS,0.0547000017832033,25.0,16.0
|
||||
maze10x10,BFS,0.0569000003451947,25.0,16.0
|
||||
maze10x10,BFS,0.0665000006847549,25.0,16.0
|
||||
maze10x10,BFS,0.0543999994988553,25.0,16.0
|
||||
maze10x10,BFS,0.0548999996681232,25.0,16.0
|
||||
maze10x10(среднее),BFS,0.063820000650594,25.0,16.0
|
||||
maze50x50,BFS,1.4375999999174385,972.0,176.0
|
||||
maze50x50,BFS,1.698000000033062,972.0,176.0
|
||||
maze50x50,BFS,1.5351000001828652,972.0,176.0
|
||||
maze50x50,BFS,1.5220999994198792,972.0,176.0
|
||||
maze50x50,BFS,1.574800000526011,972.0,176.0
|
||||
maze50x50,BFS,1.4951999983168207,972.0,176.0
|
||||
maze50x50,BFS,1.511999998911051,972.0,176.0
|
||||
maze50x50,BFS,1.5139999995881226,972.0,176.0
|
||||
maze50x50,BFS,1.4908999983163085,972.0,176.0
|
||||
maze50x50,BFS,1.487499997892883,972.0,176.0
|
||||
maze50x50(среднее),BFS,1.526719999310444,972.0,176.0
|
||||
maze100x100,BFS,3.02670000019134,2345.0,197.0
|
||||
maze100x100,BFS,3.52529999872786,2345.0,197.0
|
||||
maze100x100,BFS,3.663800001959317,2345.0,197.0
|
||||
maze100x100,BFS,3.517799999826821,2345.0,197.0
|
||||
maze100x100,BFS,3.506500001094537,2345.0,197.0
|
||||
maze100x100,BFS,3.690400000778027,2345.0,197.0
|
||||
maze100x100,BFS,3.396100000827573,2345.0,197.0
|
||||
maze100x100,BFS,3.629499999078689,2345.0,197.0
|
||||
maze100x100,BFS,3.8606999987678137,2345.0,197.0
|
||||
maze100x100,BFS,3.4976999995706137,2345.0,197.0
|
||||
maze100x100(среднее),BFS,3.531450000082259,2345.0,197.0
|
||||
maze_empty,BFS,8.452400001260685,5328.0,158.0
|
||||
maze_empty,BFS,8.42489999922691,5328.0,158.0
|
||||
maze_empty,BFS,8.638600000267616,5328.0,158.0
|
||||
maze_empty,BFS,8.208700000977842,5328.0,158.0
|
||||
maze_empty,BFS,8.816000001388602,5328.0,158.0
|
||||
maze_empty,BFS,8.447899999737274,5328.0,158.0
|
||||
maze_empty,BFS,8.679799997480586,5328.0,158.0
|
||||
maze_empty,BFS,8.399000002100365,5328.0,158.0
|
||||
maze_empty,BFS,8.234299999458017,5328.0,158.0
|
||||
maze_empty,BFS,8.313599999382859,5328.0,158.0
|
||||
maze_empty(среднее),BFS,8.461520000128075,5328.0,158.0
|
||||
maze_no_path,BFS,1.6376999992644414,1245.0,0.0
|
||||
maze_no_path,BFS,1.7487000004621225,1245.0,0.0
|
||||
maze_no_path,BFS,1.933600000484148,1245.0,0.0
|
||||
maze_no_path,BFS,1.8192999996244907,1245.0,0.0
|
||||
maze_no_path,BFS,1.8314999979338609,1245.0,0.0
|
||||
maze_no_path,BFS,1.9929000009142328,1245.0,0.0
|
||||
maze_no_path,BFS,1.7305000001215376,1245.0,0.0
|
||||
maze_no_path,BFS,1.6904000003705733,1245.0,0.0
|
||||
maze_no_path,BFS,1.6647000011289492,1245.0,0.0
|
||||
maze_no_path,BFS,1.733000000967877,1245.0,0.0
|
||||
maze_no_path(среднее),BFS,1.778230000127223,1245.0,0.0
|
||||
maze10x10,DFS,0.0433999994129408,24.0,16.0
|
||||
maze10x10,DFS,0.0624999993306119,24.0,16.0
|
||||
maze10x10,DFS,0.0682999998389277,24.0,16.0
|
||||
maze10x10,DFS,0.0490999991598073,24.0,16.0
|
||||
maze10x10,DFS,0.0468999969598371,24.0,16.0
|
||||
maze10x10,DFS,0.0467999998363666,24.0,16.0
|
||||
maze10x10,DFS,0.0689000007696449,24.0,16.0
|
||||
maze10x10,DFS,0.0502000002597924,24.0,16.0
|
||||
maze10x10,DFS,0.0493999978061765,24.0,16.0
|
||||
maze10x10,DFS,0.0475000015285331,24.0,16.0
|
||||
maze10x10(среднее),DFS,0.0532999994902638,24.0,16.0
|
||||
maze50x50,DFS,1.184500000817934,920.0,176.0
|
||||
maze50x50,DFS,1.274300000659423,920.0,176.0
|
||||
maze50x50,DFS,1.3567999994847924,920.0,176.0
|
||||
maze50x50,DFS,1.27749999955995,920.0,176.0
|
||||
maze50x50,DFS,1.4292000014393125,920.0,176.0
|
||||
maze50x50,DFS,1.2790999971912242,920.0,176.0
|
||||
maze50x50,DFS,1.329700000496814,920.0,176.0
|
||||
maze50x50,DFS,1.257100000657374,920.0,176.0
|
||||
maze50x50,DFS,1.4220000011846423,920.0,176.0
|
||||
maze50x50,DFS,1.372599999740487,920.0,176.0
|
||||
maze50x50(среднее),DFS,1.3182800001231954,920.0,176.0
|
||||
maze100x100,DFS,3.26380000115023,2609.0,197.0
|
||||
maze100x100,DFS,3.768599999602884,2609.0,197.0
|
||||
maze100x100,DFS,3.677199998492142,2609.0,197.0
|
||||
maze100x100,DFS,3.6672999995062128,2609.0,197.0
|
||||
maze100x100,DFS,3.9711999997962266,2609.0,197.0
|
||||
maze100x100,DFS,3.7203000028966926,2609.0,197.0
|
||||
maze100x100,DFS,3.739499999937834,2609.0,197.0
|
||||
maze100x100,DFS,3.717999999935273,2609.0,197.0
|
||||
maze100x100,DFS,3.63140000263229,2609.0,197.0
|
||||
maze100x100,DFS,3.789499998674728,2609.0,197.0
|
||||
maze100x100(среднее),DFS,3.6946800002624514,2609.0,197.0
|
||||
maze_empty,DFS,5.714499999157852,5328.0,2578.0
|
||||
maze_empty,DFS,5.989400000544265,5328.0,2578.0
|
||||
maze_empty,DFS,5.901900000026217,5328.0,2578.0
|
||||
maze_empty,DFS,5.935400000453228,5328.0,2578.0
|
||||
maze_empty,DFS,5.898100000194972,5328.0,2578.0
|
||||
maze_empty,DFS,6.119699999544537,5328.0,2578.0
|
||||
maze_empty,DFS,5.7996000032289885,5328.0,2578.0
|
||||
maze_empty,DFS,6.074900000385242,5328.0,2578.0
|
||||
maze_empty,DFS,5.99549999969895,5328.0,2578.0
|
||||
maze_empty,DFS,5.661700000928249,5328.0,2578.0
|
||||
maze_empty(среднее),DFS,5.90907000041625,5328.0,2578.0
|
||||
maze_no_path,DFS,2.58909999683965,1245.0,0.0
|
||||
maze_no_path,DFS,1.87980000191601,1245.0,0.0
|
||||
maze_no_path,DFS,1.6818000003695488,1245.0,0.0
|
||||
maze_no_path,DFS,1.8071000013151208,1245.0,0.0
|
||||
maze_no_path,DFS,1.6453999996883797,1245.0,0.0
|
||||
maze_no_path,DFS,1.7989999978453852,1245.0,0.0
|
||||
maze_no_path,DFS,1.778600002580788,1245.0,0.0
|
||||
maze_no_path,DFS,1.668100001552375,1245.0,0.0
|
||||
maze_no_path,DFS,1.6705999987607356,1245.0,0.0
|
||||
maze_no_path,DFS,1.7055999996955509,1245.0,0.0
|
||||
maze_no_path(среднее),DFS,1.8225100000563543,1245.0,0.0
|
||||
maze10x10,A*,0.0639999998384155,24.0,16.0
|
||||
maze10x10,A*,0.0728000013623386,24.0,16.0
|
||||
maze10x10,A*,0.0684000006003771,24.0,16.0
|
||||
maze10x10,A*,0.0645000000076834,24.0,16.0
|
||||
maze10x10,A*,0.0641000005998648,24.0,16.0
|
||||
maze10x10,A*,0.0661000012769363,24.0,16.0
|
||||
maze10x10,A*,0.0680000011925585,24.0,16.0
|
||||
maze10x10,A*,0.0658999997540377,24.0,16.0
|
||||
maze10x10,A*,0.0686999992467463,24.0,16.0
|
||||
maze10x10,A*,0.0715000023774337,24.0,16.0
|
||||
maze10x10(среднее),A*,0.0674000006256392,24.0,16.0
|
||||
maze50x50,A*,1.6070000019681174,763.0,176.0
|
||||
maze50x50,A*,1.840099997934885,763.0,176.0
|
||||
maze50x50,A*,1.7380999997840263,763.0,176.0
|
||||
maze50x50,A*,1.808999997592764,763.0,176.0
|
||||
maze50x50,A*,1.6594000007899012,763.0,176.0
|
||||
maze50x50,A*,1.821499998186482,763.0,176.0
|
||||
maze50x50,A*,1.6746000001148786,763.0,176.0
|
||||
maze50x50,A*,2.4415000007138588,763.0,176.0
|
||||
maze50x50,A*,2.8442000002542045,763.0,176.0
|
||||
maze50x50,A*,1.8294000001333188,763.0,176.0
|
||||
maze50x50(среднее),A*,1.926479999747244,763.0,176.0
|
||||
maze100x100,A*,2.5787000013224315,1194.0,197.0
|
||||
maze100x100,A*,2.7651999989757314,1194.0,197.0
|
||||
maze100x100,A*,2.860200002032798,1194.0,197.0
|
||||
maze100x100,A*,2.8369999999995343,1194.0,197.0
|
||||
maze100x100,A*,2.906600002461346,1194.0,197.0
|
||||
maze100x100,A*,2.7929999996558763,1194.0,197.0
|
||||
maze100x100,A*,3.06319999799598,1194.0,197.0
|
||||
maze100x100,A*,2.834499999153195,1194.0,197.0
|
||||
maze100x100,A*,2.7511999978742097,1194.0,197.0
|
||||
maze100x100,A*,2.793700001348043,1194.0,197.0
|
||||
maze100x100(среднее),A*,2.8183300000819145,1194.0,197.0
|
||||
maze_empty,A*,13.580099999671802,5328.0,158.0
|
||||
maze_empty,A*,13.65030000306433,5328.0,158.0
|
||||
maze_empty,A*,13.666799997736234,5328.0,158.0
|
||||
maze_empty,A*,14.009900001838105,5328.0,158.0
|
||||
maze_empty,A*,13.549700001021847,5328.0,158.0
|
||||
maze_empty,A*,13.690499999938766,5328.0,158.0
|
||||
maze_empty,A*,13.920800000050804,5328.0,158.0
|
||||
maze_empty,A*,13.680399999429936,5328.0,158.0
|
||||
maze_empty,A*,13.70409999799449,5328.0,158.0
|
||||
maze_empty,A*,13.471199999912642,5328.0,158.0
|
||||
maze_empty(среднее),A*,13.692380000065896,5328.0,158.0
|
||||
maze_no_path,A*,2.5481999982730485,1245.0,0.0
|
||||
maze_no_path,A*,2.8395000008458737,1245.0,0.0
|
||||
maze_no_path,A*,2.7317999993101694,1245.0,0.0
|
||||
maze_no_path,A*,2.7791000029537827,1245.0,0.0
|
||||
maze_no_path,A*,2.718199997616466,1245.0,0.0
|
||||
maze_no_path,A*,2.6510000025155023,1245.0,0.0
|
||||
maze_no_path,A*,2.674000003025867,1245.0,0.0
|
||||
maze_no_path,A*,2.6954999993904494,1245.0,0.0
|
||||
maze_no_path,A*,2.705599999899277,1245.0,0.0
|
||||
maze_no_path,A*,2.7092999989690725,1245.0,0.0
|
||||
maze_no_path(среднее),A*,2.705220000279951,1245.0,0.0
|
||||
maze10x10,Dijkstra,0.0546999981452245,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0766999983170535,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564999972993973,25.0,16.0
|
||||
maze10x10,Dijkstra,0.055399999837391,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0901999992493074,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0636000004305969,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0642000013613142,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0633000017842277,25.0,16.0
|
||||
maze10x10,Dijkstra,0.1010999985737726,25.0,16.0
|
||||
maze10x10,Dijkstra,0.0564000001759268,25.0,16.0
|
||||
maze10x10(среднее),Dijkstra,0.0682099995174212,25.0,16.0
|
||||
maze50x50,Dijkstra,1.7924999992828816,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7590999996173196,972.0,176.0
|
||||
maze50x50,Dijkstra,1.8786000000545755,972.0,176.0
|
||||
maze50x50,Dijkstra,1.80720000207657,972.0,176.0
|
||||
maze50x50,Dijkstra,1.840500000980683,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7653000031714328,972.0,176.0
|
||||
maze50x50,Dijkstra,1.9654999996419065,972.0,176.0
|
||||
maze50x50,Dijkstra,1.79049999860581,972.0,176.0
|
||||
maze50x50,Dijkstra,1.797400000214111,972.0,176.0
|
||||
maze50x50,Dijkstra,1.7621000006329268,972.0,176.0
|
||||
maze50x50(среднее),Dijkstra,1.8158700004278217,972.0,176.0
|
||||
maze100x100,Dijkstra,3.954100000555627,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.249900001013884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.330399999162182,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.545499999949243,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.328899998654379,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.53189999825554,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.320200001529884,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.45179999951506,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.341399999248097,2345.0,197.0
|
||||
maze100x100,Dijkstra,4.510700000537327,2345.0,197.0
|
||||
maze100x100(среднее),Dijkstra,4.356479999842122,2345.0,197.0
|
||||
maze_empty,Dijkstra,11.241200001677498,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.333599999488795,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.416299999837063,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.310300000332065,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.522700002387865,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.251799998717615,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.823299999377925,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.53350000095088,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.488299998745788,5328.0,158.0
|
||||
maze_empty,Dijkstra,11.370600001100684,5328.0,158.0
|
||||
maze_empty(среднее),Dijkstra,11.429160000261618,5328.0,158.0
|
||||
maze_no_path,Dijkstra,2.119600001606159,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.07120000050054,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.1706000006815884,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.152000000933185,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.309299998159986,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.229900001111673,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.0933000014338177,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.175500001612818,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.386500000284286,1245.0,0.0
|
||||
maze_no_path,Dijkstra,2.2796000012021977,1245.0,0.0
|
||||
maze_no_path(среднее),Dijkstra,2.198750000752625,1245.0,0.0
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -1,183 +0,0 @@
|
|||
## Описание работы
|
||||
Схема реализованных классов:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class TextFileMazeBuilder {
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
class Maze {
|
||||
-cells: Cell[]
|
||||
-width: int
|
||||
-height: int
|
||||
-start: Cell
|
||||
-exit: Cell
|
||||
+getCell(x,y): Cell
|
||||
+getNeighbors(cell): List~Cell~
|
||||
}
|
||||
|
||||
class Cell {
|
||||
-x: int
|
||||
-y: int
|
||||
-isWall: bool
|
||||
-isStart: bool
|
||||
-isExit: bool
|
||||
-value: int
|
||||
+isPassable(): bool
|
||||
+getXY(): tuple[int, int]
|
||||
+toStr(): str
|
||||
}
|
||||
|
||||
class MazeBuilder {
|
||||
<<interface>>
|
||||
+buildFromFile(filename): Maze
|
||||
}
|
||||
|
||||
class PathFindingStrategy {
|
||||
<<interface>>
|
||||
+name(): str
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class BFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class DFS {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
class AStar {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
+heuristic(a, b): int
|
||||
}
|
||||
class Dijkstra {
|
||||
+findPath(maze, start, exit): tuple[list[tuple[int, int]], int]
|
||||
}
|
||||
|
||||
class SearchStats {
|
||||
-timeMs: float
|
||||
-visitedCells: int
|
||||
-pathLength: int
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
class MazeSolver {
|
||||
-Maze maze
|
||||
-PathFindingStrategy strategy
|
||||
-Observer observer
|
||||
+strategyName: str
|
||||
+setStrategy(strategy)
|
||||
+solve(): SearchStats
|
||||
}
|
||||
|
||||
class Observer {
|
||||
<<interface>>
|
||||
+update(event)
|
||||
}
|
||||
|
||||
class ConsoleView {
|
||||
+update(event)
|
||||
+render(maze, player_position, path)
|
||||
}
|
||||
|
||||
class Event {
|
||||
-event: str
|
||||
-maze: Maze
|
||||
-player_position: tuple[int,int]
|
||||
-path: list~Cell~
|
||||
}
|
||||
|
||||
MazeBuilder <|.. TextFileMazeBuilder
|
||||
MazeBuilder --> Maze : creates
|
||||
PathFindingStrategy <|.. BFS
|
||||
PathFindingStrategy <|.. DFS
|
||||
PathFindingStrategy <|.. AStar
|
||||
PathFindingStrategy <|.. Dijkstra
|
||||
MazeSolver --> PathFindingStrategy : uses
|
||||
MazeSolver --> Maze : uses
|
||||
Maze --> Cell : uses
|
||||
MazeSolver --> SearchStats : return
|
||||
Observer <|.. ConsoleView
|
||||
ConsoleView --> Event : get
|
||||
MazeSolver --> Observer : notifies
|
||||
```
|
||||
1. Листинги ключевых классов (можно выборочно) или ссылка на репозиторий.
|
||||
- Классы `Cell` и `Maze` представлены в папке `source/classes/`
|
||||
- Реализации интерфейса `Builder` и класса `TextFileMazeBuilder` находятся в `source/builder/`
|
||||
- Реализации интерфейса `Observer` и класса `ConsoleView` находятся в `source/observer/`
|
||||
- Интерфейс `strategy`, класс `MazeSolver` и реализации алгоритмов BFS, DFS, A*, Дейкстра находятся в папке `source/strategy/`
|
||||
## Результаты экспериментов
|
||||
Все результаты находятся в `/data/cvs/banchmark.csv`, тесты запускаются через файл `benchmark.ipynb`. Лабиринты, на которых проходили тесты, находятся в директори `mazes/benchmarks/`
|
||||
Проведём 10 замеров и отобразим результаты на графиках (пунктиром отмечены среднее значение)
|
||||
![[10x10.pdf]]
|
||||
![[50x50.pdf]]
|
||||
![[100x100.pdf]]
|
||||
![[empty.pdf]]
|
||||
![[no_path.pdf]]
|
||||
|
||||
Заполним таблицу для количества посещённых клеток для каждого алгоритма:
|
||||
|
||||
| Лабиринт | BFS | DFS | A* | Дейкстра |
|
||||
| :------------: | :--: | :--: | :--: | :------: |
|
||||
| $10\times10$ | 25 | 24 | 24 | 25 |
|
||||
| $50\times50$ | 972 | 920 | 763 | 972 |
|
||||
| $100\times100$ | 2345 | 2609 | 1194 | 2345 |
|
||||
| Пустой | 5328 | 5328 | 5328 | 5328 |
|
||||
| Без выхода | 1245 | 1245 | 1245 | 1245
|
||||
|
||||
## Анализ результатов
|
||||
- **DFS** быстрее на большинстве лабиринтов, но путь может быть неоптимальным
|
||||
В качестве демонстрации, сравним работу DFS и BFS на небольшом пустом лабиринте:
|
||||
```
|
||||
BFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.8261000002676155 ms
|
||||
visited cells: 315
|
||||
path length: 43
|
||||
```
|
||||
```
|
||||
DFS
|
||||
Путь найден:
|
||||
#####################################
|
||||
#S..................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#...................................#
|
||||
# .#
|
||||
#...................................#
|
||||
#. #
|
||||
#..................................E#
|
||||
#####################################
|
||||
time: 0.6825999989814591 ms
|
||||
visited cells: 315
|
||||
path length: 179
|
||||
```
|
||||
Как видно по примеру DFS нашёл путь быстрее (0.68 против 0.82 мс), но длина найденного маршрута 179 клеток, в то время как путь, найденный BFS состоит из 43 клеток.
|
||||
#### A*:
|
||||
- По таблице видно, что A* проходит меньше всего клеток. Это происходит, так как идея алгоритма в том что он отдаёт приоритет клеткам, которые ближе к цели.
|
||||
- На практике медленнее DFS из-за операций с кучей (O(log n) на каждый шаг)
|
||||
|
||||
#### Dijkstra:
|
||||
- По сложности аналогичен BFS для лабиринтов без весов, но медленнее BFS из-за приоритетной очереди.
|
||||
- Имеет смысл на взвешенных графах
|
||||
|
||||
## Выводы
|
||||
Использование ООП и паттернов дало:
|
||||
- расширяемость - лёгкость добавления нового алгоритма поиска без изменения текущей структуры и существующих классов
|
||||
- гибкость - можно менять алгоритмы поиска, конструкторы лабиринтов и способы отображения так же без изменения уже существующих
|
||||
- Лёгкость тестирования - можно тестировать каждый элемент независимо
|
||||
Без этого было бы сложно внедрять новые реализации классов, способы отображения или создания лабиринта или изменять существующие алгоритмы.
|
||||
Но реализация интерфейсов и унификация классов увеличили объём кода и так же наложили ограничения на обрабатываемые данные.
|
||||
|
||||
По скорости лучшим по большинству тестов стал DFS. Второй по скорости BFS, так же он находит самый короткий путь, но при усложнении лабиринта(увеличении развилок и размера) начинает проигрывать A*.
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ### # # # ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # ##### ###
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
#################################################################################################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#################################################################################################################
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#####################################################
|
||||
# S # # # # # # # # #
|
||||
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||
# # # # # # # # # # # #
|
||||
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||
# # # # # # # # # # # # # # #
|
||||
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||
# # # # # # # # # # # # # #
|
||||
# ############# # # ### ##### ##### ### ##### ### # #
|
||||
# # # # # # # # # # # #
|
||||
### # # # ########### ##### # ### ### ######### ### #
|
||||
# # # # # # # # # # # # # #
|
||||
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||
# # # # # # # # # # # # # # # #
|
||||
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||
# # # # # # # # # # # # # #
|
||||
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||
# # # # # # # # # # # #
|
||||
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # ############# ##### ##### ##### ### # ##### # #
|
||||
# # # # # # # # # # # # # #
|
||||
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||
# # # # # # # # # # #
|
||||
### # # ####### # ### ############# # # # ### ### # #
|
||||
# # # # # # # # # # # # # #
|
||||
### # ######### ####### # ######### ### ##### ##### #
|
||||
# # # # # E # # # # # #
|
||||
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||
# # # # # # # # # # # # #
|
||||
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||
# # # # # # # # # # # # # # #
|
||||
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # #
|
||||
# ############# ### ### # ### # # ### ### ### ##### #
|
||||
# # # # # # # # # # # # # #
|
||||
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||
# # # # # # # # # # # # #
|
||||
# ##### ##### ### ########### ####### ##### ### #####
|
||||
# # # # # # # # # # # # #
|
||||
# # # ##### # # ### # ### # # # # ### ### # #########
|
||||
# # # # # # # # # #
|
||||
#####################################################
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
S # #####
|
||||
## # # E#
|
||||
# # ###
|
||||
### ## # #
|
||||
# #
|
||||
##########
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#######################################################################################################
|
||||
# # # # # # # # # # # #
|
||||
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||
# # # # # # # S # # # # # # # # # # # # # # #
|
||||
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||
# # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||
# # # # # # # # # # # # # # # # # # # # # #
|
||||
#######################################################################################################
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#####################################
|
||||
#S #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# E#
|
||||
#####################################
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#######################
|
||||
# # # # # # #
|
||||
### ### ##### # # # ###
|
||||
# # # # # #
|
||||
# # # ##### ### ##### #
|
||||
# # # # # #
|
||||
##### ### # ######### #
|
||||
# #
|
||||
##### # # ### ####### #
|
||||
# # # # # # #
|
||||
########### # ### ### #
|
||||
# # # # # # # #
|
||||
# ### # # ### # ### ###
|
||||
# # # # # # #
|
||||
# ### ####### # # ### #
|
||||
# # # # #
|
||||
### ####### ### #######
|
||||
# # # #
|
||||
########### # ##### # #
|
||||
# # # # #
|
||||
##### ####### ##### # #
|
||||
# # # #
|
||||
#######################
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #### #
|
||||
# E #
|
||||
####################
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
####################
|
||||
#S #
|
||||
# ########## #
|
||||
# #### #
|
||||
# ######## #
|
||||
# #
|
||||
# ####### #######
|
||||
# #E #
|
||||
####################
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .builder import *
|
||||
from .classes import *
|
||||
from .observer import *
|
||||
from .strategy import *
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .builder import MazeBuilder
|
||||
from .text_file_maze_builder import TextFileMazeBuilder
|
||||
|
||||
__all__ = ['MazeBuilder', 'TextFileMazeBuilder']
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes.maze import Maze
|
||||
|
||||
class MazeBuilder(ABC):
|
||||
@abstractmethod
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
pass
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
from source.classes.maze import Maze, Cell
|
||||
from .builder import MazeBuilder
|
||||
|
||||
|
||||
class TextFileMazeBuilder(MazeBuilder):
|
||||
def buildFromFile(self, filename: str) -> Maze:
|
||||
"""Получает лабиринт из текстового файла"""
|
||||
with open(filename) as f:
|
||||
data = f.read().splitlines()
|
||||
x, y = 0, 0
|
||||
width = len(data[0])
|
||||
height = len(data)
|
||||
|
||||
cells = [[None] * width for _ in range(height)]
|
||||
|
||||
start, c_exit = None, None
|
||||
|
||||
for line in data:
|
||||
x = 0
|
||||
for c in line.strip():
|
||||
if c == 'S':
|
||||
cells[y][x] = Cell(x, y, isStart=True)
|
||||
start = cells[y][x]
|
||||
x += 1
|
||||
elif c == 'E':
|
||||
cells[y][x] = Cell(x, y, isExit=True)
|
||||
c_exit = cells[y][x]
|
||||
x += 1
|
||||
elif c == '#':
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
elif c == ' ':
|
||||
cells[y][x] = Cell(x, y)
|
||||
x += 1
|
||||
else:
|
||||
print(f'Обнаружен неизвестный символ({c}) в файле лабиринта\nfilename: {filename}\nОн заменён на стену')
|
||||
cells[y][x] = Cell(x, y, isWall=True)
|
||||
x += 1
|
||||
|
||||
y += 1
|
||||
|
||||
if start == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен вход!\nfilename: {filename}')
|
||||
|
||||
if c_exit == None:
|
||||
raise ValueError(f'В файле лабиринта не обнаружен выход!\nfilename: {filename}')
|
||||
|
||||
return Maze(
|
||||
cells=cells,
|
||||
width=width,
|
||||
height=height,
|
||||
start=start,
|
||||
exit_cell=c_exit
|
||||
)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .cell import Cell
|
||||
from .maze import Maze
|
||||
|
||||
__all__ = ['Cell', 'Maze']
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
class Cell:
|
||||
"""
|
||||
Клетка лабиринта
|
||||
|
||||
`x, y` - координаты клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
|
||||
def __init__(self, x: int, y: int, isWall=False, isStart=False, isExit=False, value=1):
|
||||
"""
|
||||
Создание клетки лабиринта
|
||||
|
||||
`x` - столбец клетки в лабиринте
|
||||
`y` - строка клетки в лабиринте
|
||||
|
||||
`isWall` - Является ли клетка стеной
|
||||
|
||||
`isStart` - Является ли клетка стартом
|
||||
|
||||
`isExit` - Является ли клетка выходом лабиринта
|
||||
|
||||
`value` - Вес клетки
|
||||
"""
|
||||
self.__x = x
|
||||
self.__y = y
|
||||
self.isWall = isWall
|
||||
self.isStart = isStart
|
||||
self.isExit = isExit
|
||||
self.__value = value
|
||||
pass
|
||||
|
||||
@property
|
||||
def isPassable(self) -> bool:
|
||||
"""возвращает `True` для прохода, если клетка не стена"""
|
||||
return not self.isWall
|
||||
|
||||
@property
|
||||
def x(self) -> int:
|
||||
"""Возвращает координату клетки по оси X"""
|
||||
return self.__x
|
||||
|
||||
@property
|
||||
def y(self) -> int:
|
||||
"""Возвращает координату клетки по оси Y"""
|
||||
return self.__y
|
||||
|
||||
def getXY(self) -> tuple[int, int]:
|
||||
"""Возвращает кортеж координат в формате `(x, y)`"""
|
||||
return self.__x, self.__y
|
||||
|
||||
@property
|
||||
def value(self) -> int:
|
||||
"""Возвращает вес клетки"""
|
||||
return self.__value
|
||||
|
||||
def toStr(self) -> str:
|
||||
"""
|
||||
Возвращает строчкое представление клетки
|
||||
|
||||
`#` - Стена
|
||||
|
||||
`S` - Начало лабиринта
|
||||
|
||||
`E` - Конец лабиринта
|
||||
|
||||
` `(пробел) - свободный проход
|
||||
|
||||
`<int>` - Вес клетки
|
||||
"""
|
||||
if self.isWall:
|
||||
return '#'
|
||||
elif self.isStart:
|
||||
return 'S'
|
||||
elif self.isExit:
|
||||
return 'E'
|
||||
else:
|
||||
return ' '
|
||||
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
from .cell import Cell
|
||||
|
||||
class Maze:
|
||||
"""Лабиринт"""
|
||||
def __init__(self, cells, width: int, height: int, start: Cell, exit_cell: Cell):
|
||||
self.cells = cells
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.start = start
|
||||
self.exit = exit_cell
|
||||
pass
|
||||
|
||||
def getCell(self, x: int, y: int) -> Cell:
|
||||
return self.cells[y][x] # строка стобец
|
||||
|
||||
def getNeighbors(self, cell) -> list[Cell]:
|
||||
"""Возвращает список соседних проходимых клеток (вверх, вниз, влево, вправо, если в пределах границ и не стена)."""
|
||||
neighbors = []
|
||||
|
||||
c_x, c_y = cell.getXY()
|
||||
|
||||
if c_y - 1 >= 0 and not self.cells[c_y - 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y - 1][c_x])
|
||||
|
||||
if c_y + 1 < self.height and not self.cells[c_y + 1][c_x].isWall:
|
||||
neighbors.append(self.cells[c_y + 1][c_x])
|
||||
|
||||
if c_x - 1 >= 0 and not self.cells[c_y][c_x - 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x - 1])
|
||||
|
||||
if c_x + 1 < self.width and not self.cells[c_y][c_x + 1].isWall:
|
||||
neighbors.append(self.cells[c_y][c_x + 1])
|
||||
|
||||
return neighbors
|
||||
|
||||
def printer(self):
|
||||
"""Выводит в консоль лабиринт (отладочное)"""
|
||||
for line in self.cells:
|
||||
for c in line:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
def info(self):
|
||||
"""Основная информация о лабиринте"""
|
||||
print(f'height: {self.height}\nwidth: {self.width}\nstart: {self.start.getXY()}\nexit: {self.exit.getXY()}\ncount cells: {self.height * self.width}')
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
from .console_view import ConsoleView
|
||||
from .observer import Observer, Event
|
||||
|
||||
__all__ = ['ConsoleView', 'Observer', 'Event']
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import os
|
||||
|
||||
|
||||
from .observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
class ConsoleView(Observer):
|
||||
|
||||
def update(self, event: Event):
|
||||
"""Вывод состояния лабиринта на экран
|
||||
|
||||
`maze_loaded` - Лабиринт загружен
|
||||
|
||||
`path_found` - Отображает лабиринт и маршрут в нём (символом `*`)
|
||||
|
||||
`move` - Выводит лабиринт и позицию игрока в нём (символом `P`)
|
||||
|
||||
"""
|
||||
if event.event == "path_found":
|
||||
print("Путь найден:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "move":
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
elif event.event == "maze_loaded":
|
||||
print("Загружен лабиринт:")
|
||||
self.render(
|
||||
event.maze,
|
||||
event.player_position,
|
||||
event.path
|
||||
)
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def render(self, maze:Maze, player_position: tuple[int, int], path: list):
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
||||
# Если path содержит объекты Cell, преобразуем в координаты
|
||||
if path and isinstance(path[0], Cell):
|
||||
path_xy = [cell.getXY() for cell in path]
|
||||
else:
|
||||
path_xy = path
|
||||
|
||||
# path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
for line in maze.cells:
|
||||
for c in line:
|
||||
if c.getXY() == player_position:
|
||||
print('P', end='')
|
||||
elif c.toStr() in ["S", "E"]:
|
||||
print(c.toStr(), end='')
|
||||
elif c.getXY() in path_xy:
|
||||
print('.', end='')
|
||||
else:
|
||||
print(c.toStr(), end='')
|
||||
|
||||
print()
|
||||
|
||||
# def render_xy(self, maze: Maze, player_position: tuple[int, int], path: list[tuple[int, int]]):
|
||||
# os.system('cls' if os.name == 'nt' else 'clear')
|
||||
# # path_xy = [cell.getXY() for cell in path]
|
||||
|
||||
# for line in maze.cells:
|
||||
# for c in line:
|
||||
# if c.getXY() == player_position:
|
||||
# print('P', end='')
|
||||
# elif c.getXY() in path:
|
||||
# print('*', end='')
|
||||
# else:
|
||||
# print(c.toStr(), end='')
|
||||
# print()
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
# import os
|
||||
|
||||
from source.classes import Maze
|
||||
|
||||
|
||||
class Event:
|
||||
def __init__(self, event: str, maze: Maze, player_position: tuple[int, int], path):
|
||||
self.event = event
|
||||
self.maze = maze
|
||||
self.player_position = player_position
|
||||
self.path = path
|
||||
|
||||
|
||||
class Observer(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def update(self, event: Event):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
from collections import deque
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class BFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self):
|
||||
"""Возвращает название метода"""
|
||||
return "BFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
queue = deque([start_cell])
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while queue:
|
||||
current = queue.popleft()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
queue.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
class DFS(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "DFS"
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
# print(f"Старт: {start_cell.getXY()}")
|
||||
# print(f"Выход: {exit_cell.getXY()}")
|
||||
# print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")
|
||||
|
||||
stack = [start_cell]
|
||||
|
||||
parents = {start_cell.getXY(): Cell(-1, -1)}
|
||||
visited = {start_cell.getXY()}
|
||||
count_visited = 1
|
||||
|
||||
while stack:
|
||||
current = stack.pop()
|
||||
|
||||
if current.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=parents,
|
||||
start=start_cell,
|
||||
end=current
|
||||
), count_visited
|
||||
|
||||
# neigbours = maze.getNeighbors(current)
|
||||
# print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")
|
||||
|
||||
for neighbor in maze.getNeighbors(current):
|
||||
neig_xy = neighbor.getXY()
|
||||
|
||||
if neig_xy not in visited:
|
||||
visited.add(neig_xy)
|
||||
parents[neig_xy] = current
|
||||
count_visited += 1
|
||||
# new_path = current_path + [neigbour]
|
||||
stack.append(neighbor)
|
||||
|
||||
return [], count_visited
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class Dijkstra(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Возвращает название метода"""
|
||||
return "Dijkstra"
|
||||
|
||||
|
||||
def findPath(self, maze: Maze):
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
heappush(queue, (0, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_cost + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
heappush(queue, (new_cost, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
from .strategy import PathFindingStrategy, reconstruct_path
|
||||
from .maze_solver import MazeSolver
|
||||
|
||||
|
||||
from .bfs import BFS
|
||||
from .dfs import DFS
|
||||
from .astar import AStar
|
||||
from .dijkstra import Dijkstra
|
||||
# from .maze_solver import MazeSolver
|
||||
# from .strategy import PathFindingStrategy, reconstruct_path
|
||||
|
||||
__all__ = ['BFS', 'DFS', 'AStar', 'Dijkstra', 'MazeSolver', 'PathFindingStrategy', 'reconstruct_path']
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
from heapq import *
|
||||
|
||||
|
||||
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||
from source.classes import Maze, Cell
|
||||
|
||||
|
||||
class AStar(PathFindingStrategy):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "A*"
|
||||
|
||||
def heuristic(self, a: Cell, b: Cell) -> int:
|
||||
x1, y1 = a.getXY()
|
||||
x2, y2 = b.getXY()
|
||||
|
||||
return abs(x1 - x2) + abs(y1 - y2)
|
||||
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
start_cell = maze.start
|
||||
exit_cell = maze.exit
|
||||
|
||||
queue = []
|
||||
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||
|
||||
start_h = self.heuristic(start_cell, exit_cell)
|
||||
|
||||
heappush(queue, (start_h, counter, start_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited = {start_cell.getXY(): 0}
|
||||
came_from = {start_cell.getXY(): None}
|
||||
visited_count = 1
|
||||
|
||||
while queue:
|
||||
current_cost, _, current_cell = heappop(queue)
|
||||
current_g = cost_visited[current_cell.getXY()]
|
||||
|
||||
if current_cell.getXY() == exit_cell.getXY():
|
||||
return reconstruct_path(
|
||||
came_from=came_from,
|
||||
start=start_cell,
|
||||
end=current_cell
|
||||
), visited_count
|
||||
|
||||
next_cells = maze.getNeighbors(current_cell)
|
||||
|
||||
for next_cell in next_cells:
|
||||
neighbor_cost = next_cell.value
|
||||
neighbor_cell_xy = next_cell.getXY()
|
||||
|
||||
new_cost = current_g + neighbor_cost
|
||||
|
||||
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||
priority = new_cost + self.heuristic(next_cell, exit_cell)
|
||||
|
||||
heappush(queue, (priority, counter, next_cell))
|
||||
counter += 1
|
||||
|
||||
cost_visited[neighbor_cell_xy] = new_cost
|
||||
came_from[neighbor_cell_xy] = current_cell
|
||||
visited_count += 1
|
||||
|
||||
return [], visited_count
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import time
|
||||
|
||||
|
||||
from .strategy import PathFindingStrategy
|
||||
from source.observer import Observer, Event
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class MazeSolver:
|
||||
def __init__(self, maze: Maze, strategy: PathFindingStrategy, observer: Observer):
|
||||
self.maze = maze
|
||||
self.strategy = strategy
|
||||
self.observer = observer
|
||||
|
||||
def strategyName(self) -> str:
|
||||
return self.strategy.name
|
||||
|
||||
def setStrategy(self, strategy: PathFindingStrategy):
|
||||
self.strategy = strategy
|
||||
|
||||
def solve(self):
|
||||
start_time = time.perf_counter()
|
||||
path, visited_cells = self.strategy.findPath(self.maze)
|
||||
finish_time = time.perf_counter()
|
||||
|
||||
self.observer.update(Event(
|
||||
event="path_found",
|
||||
maze=self.maze,
|
||||
player_position=self.maze.exit,
|
||||
path=path
|
||||
))
|
||||
|
||||
return SearchStats(
|
||||
timeMs=(finish_time - start_time) * 1000,
|
||||
visitedCells=visited_cells,
|
||||
pathLength=len(path),
|
||||
path=path
|
||||
)
|
||||
|
||||
|
||||
|
||||
class SearchStats:
|
||||
"""Общая информация о тесте алгоритма"""
|
||||
def __init__(self, timeMs: float, visitedCells: int, pathLength: int, path: list[Cell]):
|
||||
self.timeMs = timeMs
|
||||
self.visitedCells = visitedCells
|
||||
self.pathLength = pathLength
|
||||
self.path = path
|
||||
|
||||
def show(self):
|
||||
"""Вывод информации о тесте в консоль"""
|
||||
print(f'time: {self.timeMs} ms\nvisited cells: {self.visitedCells}\npath length: {self.pathLength}')
|
||||
|
||||
# def toStr(self) -> str:
|
||||
# return f'{self.timeMs} {self.visitedCells} {self.pathLength}'
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from source.classes import Cell, Maze
|
||||
|
||||
|
||||
class PathFindingStrategy(ABC):
|
||||
"""Интерфейс для семейства алгоритмов поиска пути от старта до выхода."""
|
||||
|
||||
@abstractmethod
|
||||
def findPath(self, maze: Maze) -> tuple[list[tuple[int, int]], int]:
|
||||
"""Возвращающим список координат клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток."""
|
||||
pass
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
"""Возвращает название алгоритма"""
|
||||
pass
|
||||
|
||||
# class CellAlgorithm(Cell):
|
||||
# def __init__(self, x: int, y: int, parent: Cell, exitDist: float, isWall=False, isStart=False, isExit=False, value=1):
|
||||
# super().__init__(x, y, isWall, isStart, isExit, value)
|
||||
# self.parent = parent
|
||||
# self.ExitDist = exitDist
|
||||
# self.weight = self.value + exitDist
|
||||
|
||||
|
||||
def reconstruct_path(came_from: dict, start: Cell, end: Cell) -> list[Cell]:
|
||||
"""Восстановление пути по словарю предшественников"""
|
||||
path = []
|
||||
current = end
|
||||
|
||||
# Идём от конца к началу по цепочке came_from
|
||||
while current.getXY() != start.getXY():
|
||||
path.append(current)
|
||||
current = came_from[current.getXY()]
|
||||
|
||||
path.append(start)
|
||||
return path[::-1]
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user