Добавление чистой папки второй лабораторной рабты
This commit is contained in:
parent
7fec6872a1
commit
d8ae32af35
11255
stepushovgs/labyrinth/benchmark.ipynb
Normal file
11255
stepushovgs/labyrinth/benchmark.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
221
stepushovgs/labyrinth/docs/data/csv/banchmark.csv
Normal file
221
stepushovgs/labyrinth/docs/data/csv/banchmark.csv
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
Лабиринт,Алгоритм,Время,Посещено клеток,Длина пути
|
||||||
|
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
|
||||||
|
BIN
stepushovgs/labyrinth/docs/data/img/100x100.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/100x100.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/10x10.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/10x10.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/50x50.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/50x50.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/empty.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/empty.pdf
Normal file
Binary file not shown.
BIN
stepushovgs/labyrinth/docs/data/img/no_path.pdf
Normal file
BIN
stepushovgs/labyrinth/docs/data/img/no_path.pdf
Normal file
Binary file not shown.
745
stepushovgs/labyrinth/docs/data/main.ipynb
Normal file
745
stepushovgs/labyrinth/docs/data/main.ipynb
Normal file
File diff suppressed because one or more lines are too long
183
stepushovgs/labyrinth/docs/Отчёт.md
Normal file
183
stepushovgs/labyrinth/docs/Отчёт.md
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
## Описание работы
|
||||||
|
Схема реализованных классов:
|
||||||
|
|
||||||
|
```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*.
|
||||||
103
stepushovgs/labyrinth/mazes/benchmarks/maze100x100.txt
Normal file
103
stepushovgs/labyrinth/mazes/benchmarks/maze100x100.txt
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
#######################################################################################################
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||||
|
# # # # # # # S # # # # # # # # # # # # # # #
|
||||||
|
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||||
|
# # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||||
|
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||||
|
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
#######################################################################################################
|
||||||
6
stepushovgs/labyrinth/mazes/benchmarks/maze10x10.txt
Normal file
6
stepushovgs/labyrinth/mazes/benchmarks/maze10x10.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
S # #####
|
||||||
|
## # # E#
|
||||||
|
# # ###
|
||||||
|
### ## # #
|
||||||
|
# #
|
||||||
|
##########
|
||||||
53
stepushovgs/labyrinth/mazes/benchmarks/maze50x50.txt
Normal file
53
stepushovgs/labyrinth/mazes/benchmarks/maze50x50.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#####################################################
|
||||||
|
# S # # # # # # # # #
|
||||||
|
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||||
|
# # # # # # # # # # # # # # # #
|
||||||
|
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ############# # # ### ##### ##### ### ##### ### # #
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
### # # # ########### ##### # ### ### ######### ### #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||||
|
# # # # # # # # # # # # # # # #
|
||||||
|
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# # # ############# ##### ##### ##### ### # ##### # #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||||
|
# # # # # # # # # # #
|
||||||
|
### # # ####### # ### ############# # # # ### ### # #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
### # ######### ####### # ### # # # ### ##### ##### #
|
||||||
|
# # # # # E # # # # # #
|
||||||
|
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
# ############# ### ### # ### # # ### ### ### ##### #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
# ##### ##### ### ########### ####### ##### ### #####
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
# # # ##### # # ### # ### # # # # ### ### # ##### ###
|
||||||
|
# # # # # # # # # #
|
||||||
|
#####################################################
|
||||||
50
stepushovgs/labyrinth/mazes/benchmarks/maze_empty.txt
Normal file
50
stepushovgs/labyrinth/mazes/benchmarks/maze_empty.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#################################################################################################################
|
||||||
|
#S #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# E#
|
||||||
|
#################################################################################################################
|
||||||
53
stepushovgs/labyrinth/mazes/benchmarks/maze_no_path.txt
Normal file
53
stepushovgs/labyrinth/mazes/benchmarks/maze_no_path.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#####################################################
|
||||||
|
# S # # # # # # # # #
|
||||||
|
####### ##### # ##### # # ### ### ### ### ##### # ###
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
# ##### # ####### ##### ### ####### ### ### # # # # #
|
||||||
|
# # # # # # # # # # # # # # # #
|
||||||
|
# ### # ##### # # # # ##### # # # ##### # ### ### ###
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# ### # # ### # ### # ### # # ######### ##### # ### #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
### # ### ####### ### # ### ### ####### # ### ### # #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# ### # # # # # ##### ### # ### ### # ######### #####
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ############# # # ### ##### ##### ### ##### ### # #
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
### # # # ########### ##### # ### ### ######### ### #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ### # ####### # ##### # ### ### ####### # # # ### #
|
||||||
|
# # # # # # # # # # # # # # # #
|
||||||
|
# # # ### # # ####### # ### ### ### ##### ### #######
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
### ### ##### # # ### ### ### # ### # ######### ### #
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
# # # ### ##### # # # # ########### # ### # # # # ###
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# # # ############# ##### ##### ##### ### # ##### # #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# ##### ### ##### # # # ### # ### ####### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
### ### # ######### # ### # ### # # # # ### ##### # #
|
||||||
|
# # # # # # # # # # #
|
||||||
|
### # # ####### # ### ############# # # # ### ### # #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
### # ######### ####### # ######### ### ##### ##### #
|
||||||
|
# # # # # E # # # # # #
|
||||||
|
# ### ##### ### # ### ### # ####### # ##### # #######
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # ##### # ####### ### # ### ##### # # # ###
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
####### ##### # ### ### # ##### ##### ### ##### ### #
|
||||||
|
# # # # # # # # # # # # # # #
|
||||||
|
# # # # # # # # ##### ### # # # ### ### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # #
|
||||||
|
# ############# ### ### # ### # # ### ### ### ##### #
|
||||||
|
# # # # # # # # # # # # # #
|
||||||
|
# # # # # # ### ### # ##### ### ### ### # ### ### # #
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
# ##### ##### ### ########### ####### ##### ### #####
|
||||||
|
# # # # # # # # # # # # #
|
||||||
|
# # # ##### # # ### # ### # # # # ### ### # #########
|
||||||
|
# # # # # # # # # #
|
||||||
|
#####################################################
|
||||||
6
stepushovgs/labyrinth/mazes/tests/test_lab.txt
Normal file
6
stepushovgs/labyrinth/mazes/tests/test_lab.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
S # #####
|
||||||
|
## # # E#
|
||||||
|
# # ###
|
||||||
|
### ## # #
|
||||||
|
# #
|
||||||
|
##########
|
||||||
103
stepushovgs/labyrinth/mazes/tests/test_lab100.txt
Normal file
103
stepushovgs/labyrinth/mazes/tests/test_lab100.txt
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
#######################################################################################################
|
||||||
|
# # # # # # # # # # # #
|
||||||
|
### # ##### # # # ############# ######### ### ### # # # ### # # # # # # ####### ##### ##### # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ##### # ##### ### ### ### # ##### # ####### ##### ### ##### ### ####### # # ####### ### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### ### ### ##### # ####### ### ### # ##### ##### # ########### ### ### ##### ### # ### # # # # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### # ### # ######### ##### ### # ### # ### ##### ### ### # ### # # # ### # # ##### # ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ### ### # # ### # # ####### # # # ### # ### # # # ####### # # ##### ### ### ### # ##### ### # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # ### ### # ##### # # ##### ### # ##### # ##### ##### ### # # ####### ##### # # # # # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ##### ### # ### # ### # # ### ##### ####### ### ##### ### ### # # # # # # # ######### # # ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### ### ### # ############# ### # # ### ############### # ##### # ##### ### # # ########### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ##### # ####### ##### ##### ### ### # ### ### ### ####### ##### # # ##### ##### # # # # ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # # ### ##### # # # # ##### ##### ##### ##### # ##### # ### ##### ### ### ### ### ### ########### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ####### # ### # # ##### # # ### # ########### ##### # # ### # ### # # # # ##### # ### # ####### # ###
|
||||||
|
# # # # # # # S # # # # # # # # # # # # # # #
|
||||||
|
### # ####### # ##### ##### ### # ### ### ####### # # # # ### ### # ######### # ### ### ### # # ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ########### # ### # # # # # ### ########### # # # ####### ### # ##### ### ### ### # ### ####### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ##### # # ####### ### ##### # # ######### # ##### ### # ##### ########### # # # # # ### # # ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### # ### # # # # # ### ##### ### ### ##### ##### ### # ### # ### ####### # # ### ####### # #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # ### ### ### ##### # # ##### ### # ### # # ### ### ##### ####### ####### # ##### ### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # ##### # # # # # # # ### # ### ##### ### ### ######### # # # ##### # # ### ##### ### # # ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # ####### ### ##### # ##### ####### # # ### ######### ### # # # ########### ####### ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### # ### # # # ##### ### # ### # # ####### ### # ##### # ##### ##### ### # # ####### ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ############### # # ### # ##### ### ### ### # # # ### ### # # ### # # ### ##### ### ### ####### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # ####### # ##### ### ### ##### # ####### ######### # ### # ####### # ######### # # ######### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### # ### # ### ##### # ##### # ### # ### # # # # ##### # # # ############# ####### ### # ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ##### ### # ### ##### ### # ### # # # # ##### # ### # # # # # # ### # # # ### ######### ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ##### ### ##### ##### ####### ### ########### # # # ### # # ### ####### # # # # ######### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ### ### ### ### # ##### # # ####### # # # # ####### ####### ##### ##### ####### # ##### ### ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ####### # ##### # # ### ##### ### # ####### ### ### # ##### # ### # ### ##### # ### # # # # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### # # # ##### ##### # # ####### # # ### ####### ### # ##### ### # # # ####### # # ### ### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### # ### # # ############### # ##### ############# # ##### # ### # ### # # ### # # # # ######### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ######### # ### # ####### # ####### # # # ### # ### ### # ##### ### # ##### ############### ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ### ### # ####### # ### # ### # ### # ### ##### ##### ##### ### ### # # # # # # ##### ##### ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### # ### ####### ### ####### # ### ##### # # ####### ##### ### ### # ##### # ####### # # # ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ##### # # ##### # # ### # ##### # ### # # ### ### # ### ########### ### # # ### ### ##### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### ### ##### ### # ####### ### ##### ### # ######### ##### ### ### ##### ####### ##### ### ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
########### ##### ##### # ### ### ### # ####### # # ### ### ### # # # # # ### # ##### # # # ### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ##### # ### # # # # # ### # # # ##### # ### ### # # ### ##### ####### ### # # ### ######### # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ####### # ### ### ##### ##### # ### ### ### ### # ##### # ### # # # ##### # ### ### # ######### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # ### # ##### ####### # ##### ##### ##### # # # # # ### # # ######### # ### # ####### # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ############# ### ### ##### ######### # ### ####### # ### # # ####### # ### ##### ### #######
|
||||||
|
# # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### # # # ### ##### # # ### ############### ### # # # ##### # # ##### ##### # ### ##### ##### # ###
|
||||||
|
# # # # # # # # # # # # # # # E # # # # # # # # #
|
||||||
|
# # ### ##### # ##### ### # # # ### # ### # ######### # # ##### ####### ####### ##### ####### # #######
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### ####### ### # # # ##### ######### ### ##### ####### # # # # # # # # # # ### # ### # ### # ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ####### # # ### # ### ####### # ### # # ### ####### ####### ### ### # ########### # ### #####
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ####### ######### ##### # # ### ### ### # ### # # # ##### ### # ##### ### # # # ### ###########
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
##### # # # # # # # # # ##### ##### ##### # ##### # ##### # # ### # # # # ######### ########### # ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # ### ### ####### ### ### # ### ######### ##### ##### ####### # # ##### # # # ### # ######### ### # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ### ### ####### # ### # ### ######### # ### # # ### # # # # ##### ### # # ##### ### ######### # # ###
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# ##### ### # ######### ### # ### ### # ### # ########### ### ### # ### # # ### ### ######### # ##### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
# # # # # ### # # # ##### ### # ### ### # ##### ### # ### ##### ##### ####### ##### # ### ### ### # # #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ##### # # ##### ### # # ##### ##### # # ######### ### ### ##### ### ### # ### ##### # # ### ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
### # ### # ### # ##### # # ####### # ### ### # ### # ### # # ### ### # # ##### # # ### ### # # # ### #
|
||||||
|
# # # # # # # # # # # # # # # # # # # # # #
|
||||||
|
#######################################################################################################
|
||||||
11
stepushovgs/labyrinth/mazes/tests/test_lab2.txt
Normal file
11
stepushovgs/labyrinth/mazes/tests/test_lab2.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#####################################
|
||||||
|
#S #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# #
|
||||||
|
# E#
|
||||||
|
#####################################
|
||||||
23
stepushovgs/labyrinth/mazes/tests/test_lab20x20.txt
Normal file
23
stepushovgs/labyrinth/mazes/tests/test_lab20x20.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#######################
|
||||||
|
# # # # # # #
|
||||||
|
### ### ##### # # # ###
|
||||||
|
# # # # # #
|
||||||
|
# # # ##### ### ##### #
|
||||||
|
# # # # # #
|
||||||
|
##### ### # ######### #
|
||||||
|
# #
|
||||||
|
##### # # ### ####### #
|
||||||
|
# # # # # # #
|
||||||
|
########### # ### ### #
|
||||||
|
# # # # # # # #
|
||||||
|
# ### # # ### # ### ###
|
||||||
|
# # # # # # #
|
||||||
|
# ### ####### # # ### #
|
||||||
|
# # # # #
|
||||||
|
### ####### ### #######
|
||||||
|
# # # #
|
||||||
|
########### # ##### # #
|
||||||
|
# # # # #
|
||||||
|
##### ####### ##### # #
|
||||||
|
# # # #
|
||||||
|
#######################
|
||||||
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
####################
|
||||||
|
#S #
|
||||||
|
# ########## #
|
||||||
|
# #### #
|
||||||
|
# ######## #
|
||||||
|
# #
|
||||||
|
# ####### #### #
|
||||||
|
# E #
|
||||||
|
####################
|
||||||
9
stepushovgs/labyrinth/mazes/tests/test_labNoPath.txt
Normal file
9
stepushovgs/labyrinth/mazes/tests/test_labNoPath.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
####################
|
||||||
|
#S #
|
||||||
|
# ########## #
|
||||||
|
# #### #
|
||||||
|
# ######## #
|
||||||
|
# #
|
||||||
|
# ####### #######
|
||||||
|
# #E #
|
||||||
|
####################
|
||||||
4
stepushovgs/labyrinth/source/__init__.py
Normal file
4
stepushovgs/labyrinth/source/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .builder import *
|
||||||
|
from .classes import *
|
||||||
|
from .observer import *
|
||||||
|
from .strategy import *
|
||||||
4
stepushovgs/labyrinth/source/builder/__init__.py
Normal file
4
stepushovgs/labyrinth/source/builder/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .builder import MazeBuilder
|
||||||
|
from .text_file_maze_builder import TextFileMazeBuilder
|
||||||
|
|
||||||
|
__all__ = ['MazeBuilder', 'TextFileMazeBuilder']
|
||||||
9
stepushovgs/labyrinth/source/builder/builder.py
Normal file
9
stepushovgs/labyrinth/source/builder/builder.py
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
from source.classes.maze import Maze
|
||||||
|
|
||||||
|
class MazeBuilder(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def buildFromFile(self, filename: str) -> Maze:
|
||||||
|
pass
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
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
|
||||||
|
)
|
||||||
4
stepushovgs/labyrinth/source/classes/__init__.py
Normal file
4
stepushovgs/labyrinth/source/classes/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .cell import Cell
|
||||||
|
from .maze import Maze
|
||||||
|
|
||||||
|
__all__ = ['Cell', 'Maze']
|
||||||
86
stepushovgs/labyrinth/source/classes/cell.py
Normal file
86
stepushovgs/labyrinth/source/classes/cell.py
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
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 ' '
|
||||||
|
|
||||||
|
|
||||||
46
stepushovgs/labyrinth/source/classes/maze.py
Normal file
46
stepushovgs/labyrinth/source/classes/maze.py
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
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}')
|
||||||
0
stepushovgs/labyrinth/source/command/command.py
Normal file
0
stepushovgs/labyrinth/source/command/command.py
Normal file
4
stepushovgs/labyrinth/source/observer/__init__.py
Normal file
4
stepushovgs/labyrinth/source/observer/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .console_view import ConsoleView
|
||||||
|
from .observer import Observer, Event
|
||||||
|
|
||||||
|
__all__ = ['ConsoleView', 'Observer', 'Event']
|
||||||
79
stepushovgs/labyrinth/source/observer/console_view.py
Normal file
79
stepushovgs/labyrinth/source/observer/console_view.py
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
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()
|
||||||
21
stepushovgs/labyrinth/source/observer/observer.py
Normal file
21
stepushovgs/labyrinth/source/observer/observer.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
49
stepushovgs/labyrinth/source/strategy/BFS.py
Normal file
49
stepushovgs/labyrinth/source/strategy/BFS.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
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
|
||||||
47
stepushovgs/labyrinth/source/strategy/DFS.py
Normal file
47
stepushovgs/labyrinth/source/strategy/DFS.py
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
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
|
||||||
56
stepushovgs/labyrinth/source/strategy/Dijkstra.py
Normal file
56
stepushovgs/labyrinth/source/strategy/Dijkstra.py
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
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
|
||||||
|
|
||||||
12
stepushovgs/labyrinth/source/strategy/__init__.py
Normal file
12
stepushovgs/labyrinth/source/strategy/__init__.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
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']
|
||||||
64
stepushovgs/labyrinth/source/strategy/astar.py
Normal file
64
stepushovgs/labyrinth/source/strategy/astar.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
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
|
||||||
55
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
55
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
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}'
|
||||||
39
stepushovgs/labyrinth/source/strategy/strategy.py
Normal file
39
stepushovgs/labyrinth/source/strategy/strategy.py
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
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]
|
||||||
1078
stepushovgs/labyrinth/test.ipynb
Normal file
1078
stepushovgs/labyrinth/test.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user