1
+ let dirIndication = [ "r" , "d" , "l" , "u" ]
2
+
3
+ let sleep = ( sec = 100 ) => {
4
+ return new Promise ( x => setTimeout ( x , sec ) )
5
+ }
6
+
7
+ async function createMazeGoTo ( node , from , isVisited = new Map ( ) ) {
8
+ node . addClass ( "cur" )
9
+ node . removeClass ( "wall" )
10
+ let fromdir = { "left" : 0 , "up" : 1 , "right" : 2 , "down" : 3 }
11
+ let todir = { 0 : "right" , 1 : "down" , 2 : "left" , 3 : "up" }
12
+
13
+ let shuffle = ( arr ) => {
14
+ let n = arr . length
15
+ for ( let i = n - 1 ; i >= 0 ; i -- ) {
16
+ let rand = Math . floor ( Math . random ( ) * ( i + 1 ) )
17
+ let temp = arr [ i ]
18
+ arr [ i ] = arr [ rand ]
19
+ arr [ rand ] = temp
20
+ }
21
+ return arr
22
+ }
23
+
24
+ if ( ! isVisited [ node ] ) {
25
+ isVisited . set ( node , true )
26
+ node . removeWall ( fromdir [ from ] )
27
+ let random = shuffle ( [ 0 , 1 , 2 , 3 ] )
28
+ for ( let i = 0 ; i < random . length ; ++ i ) {
29
+
30
+
31
+ await sleep ( 1 )
32
+
33
+
34
+ if ( node . neighbors [ random [ i ] ] && ! isVisited . get ( node . neighbors [ random [ i ] ] ) ) {
35
+ node . removeWall ( random [ i ] )
36
+ node . removeClass ( "cur" )
37
+ await createMazeGoTo ( node . neighbors [ random [ i ] ] , todir [ random [ i ] ] , isVisited )
38
+ node . addClass ( "cur" )
39
+ }
40
+ }
41
+ }
42
+
43
+ node . removeClass ( "cur" )
44
+ }
45
+
46
+
47
+ async function BFSsearch ( maze , start , end , isDone = new Map ( ) , parent = new Map ( ) , dis = new Map ( ) , dir = new Map ( ) ) {
48
+
49
+ let queue = new Array ( )
50
+ queue . push ( start )
51
+ dis . set ( start , 0 )
52
+ parent . set ( start , undefined )
53
+
54
+ while ( queue . length ) {
55
+ let node = queue . shift ( )
56
+ if ( ! isDone . get ( node ) ) {
57
+
58
+ await sleep ( 10 )
59
+ isDone . set ( node , true )
60
+ node . addClass ( "searching" )
61
+
62
+ if ( node == end ) {
63
+ await backtrack ( end , start , parent , dir )
64
+ break ;
65
+ }
66
+
67
+
68
+ for ( let i = 0 ; i < node . sides ; ++ i ) {
69
+ if ( ! node . border [ i ] && node . neighbors [ i ] && ! isDone . get ( node . neighbors [ i ] ) ) {
70
+ if ( ! dis . get ( node . neighbors [ i ] ) || dis . get ( node . neighbors [ i ] ) > dis . get ( node ) + 1 ) {
71
+ parent . set ( node . neighbors [ i ] , node )
72
+ dis . set ( node . neighbors [ i ] , dis [ node ] + 1 )
73
+ dir . set ( node . neighbors [ i ] , dirIndication [ i ] )
74
+ }
75
+ queue . push ( node . neighbors [ i ] )
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ async function dijkstraSearch ( maze , start , end , isDone = new Map ( ) , parent = new Map ( ) , dis = new Map ( ) , dir = new Map ( ) ) {
83
+
84
+ // start.addClass("startNode")
85
+ // end.addClass("endNode")
86
+
87
+ let queue = new Array ( )
88
+ queue . push ( start )
89
+ dis . set ( start , 0 )
90
+ parent . set ( start , undefined )
91
+
92
+ while ( queue . length ) {
93
+ let node = queue . shift ( )
94
+ if ( ! isDone . get ( node ) ) {
95
+ await sleep ( 10 )
96
+ isDone . set ( node , true )
97
+ node . addClass ( "searching" )
98
+
99
+ if ( node == end ) {
100
+ await backtrack ( end , start , parent , dir )
101
+ break ;
102
+ }
103
+
104
+
105
+ for ( let i = 0 ; i < node . sides ; ++ i ) {
106
+ if ( ! node . border [ i ] && node . neighbors [ i ] && ! isDone . get ( node . neighbors [ i ] ) ) {
107
+ if ( ! dis . get ( node . neighbors [ i ] ) || dis . get ( node . neighbors [ i ] ) > dis . get ( node ) + 1 ) {
108
+ parent . set ( node . neighbors [ i ] , node )
109
+ dis . set ( node . neighbors [ i ] , dis [ node ] + 1 )
110
+ dir . set ( node . neighbors [ i ] , dirIndication [ i ] )
111
+ }
112
+ queue . push ( node . neighbors [ i ] )
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ async function AstarSearch ( maze , start , end , isDone = new Map ( ) , gscore = new Map ( ) , fscore = new Map ( ) , parent = new Map ( ) , dir = new Map ( ) ) {
120
+ let dis = ( x , y ) => {
121
+ return Math . hypot ( x . i - y . i , x . j - y . j )
122
+ }
123
+
124
+ let getMin = ( openSet , fscore ) => {
125
+ let min = Math . min ( ...openSet . map ( el => fscore . get ( el ) ) )
126
+
127
+ for ( let i = 0 ; i < openSet . length ; i ++ ) {
128
+ if ( fscore . get ( openSet [ i ] ) == min ) {
129
+ let ans = openSet [ i ]
130
+ openSet . splice ( i , 1 )
131
+ return ans
132
+ }
133
+ }
134
+ }
135
+
136
+ let openSet = [ ]
137
+
138
+ openSet . push ( start )
139
+
140
+ parent . set ( start , undefined )
141
+ gscore . set ( start , 0 )
142
+ fscore . set ( start , dis ( start , end ) )
143
+ isDone . set ( start , true )
144
+ while ( openSet . length ) {
145
+ let curr = getMin ( openSet , fscore )
146
+ curr . addClass ( "searching" )
147
+ if ( curr == end ) {
148
+ await backtrack ( end , start , parent , dir )
149
+ return
150
+ }
151
+
152
+ isDone . set ( curr , true )
153
+
154
+ for ( let i = 0 ; i < curr . border . length ; ++ i ) {
155
+ await sleep ( 10 )
156
+
157
+ let n = curr . neighbors [ i ]
158
+ if ( n && ! curr . border [ i ] && ! isDone . get ( n ) ) {
159
+ let tempG = gscore . get ( curr ) + dis ( curr , n )
160
+
161
+ if ( ! gscore . get ( n ) || tempG < gscore . get ( n ) ) {
162
+ parent . set ( n , curr )
163
+ dir . set ( n , dirIndication [ i ] )
164
+ gscore . set ( n , tempG )
165
+ fscore . set ( n , gscore . get ( n ) + dis ( n , end ) )
166
+
167
+ }
168
+
169
+ if ( ! ( openSet . find ( el => el == n ) ) ) {
170
+ openSet . push ( n )
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ async function DFSsearch ( maze , node , end , isDone = new Map ( ) , parent = new Map ( ) , dis = new Map ( ) , dir = new Map ( ) ) {
178
+ if ( node == end ) {
179
+ await backtrack ( end , start , parent , dir )
180
+ return true
181
+ }
182
+ if ( isDone . get ( node ) ) {
183
+ return
184
+ }
185
+ isDone . set ( node , true )
186
+
187
+ node . addClass ( "searching" )
188
+ await sleep ( 10 )
189
+
190
+ for ( let i = 0 ; i < node . sides ; ++ i ) {
191
+ if ( ! node . border [ i ] && node . neighbors [ i ] && ! isDone . get ( node . neighbors [ i ] ) ) {
192
+ if ( ( ! dis . get ( node ) || dis . get ( node [ i ] ) + 1 > dis . get ( node . neighbors [ i ] ) ) ) {
193
+ dis . set ( node . neighbors [ i ] , dis . get ( node ) + 1 )
194
+ parent . set ( node . neighbors [ i ] , node )
195
+ dir . set ( node . neighbors [ i ] , dirIndication [ i ] )
196
+ }
197
+ if ( await DFSsearch ( maze , node . neighbors [ i ] , end , isDone , parent , dis , dir ) )
198
+ return true
199
+ }
200
+ }
201
+ }
202
+
203
+ async function backtrack ( end , start , parent , dir ) {
204
+ let node = end
205
+ let to = ""
206
+ while ( node ) {
207
+ await sleep ( 10 )
208
+
209
+ node . removeClass ( "searching" )
210
+ node . addClass ( "inWay" )
211
+ node . el . innerHTML = to
212
+ switch ( dir . get ( node ) ) {
213
+ case "u" :
214
+ to = '🠋'
215
+ break ;
216
+ case "d" :
217
+ to = '🠉'
218
+ break ;
219
+ case "r" :
220
+ to = '🠈'
221
+ break ;
222
+ case "l" :
223
+ to = '🠊'
224
+ break ;
225
+ }
226
+
227
+ node = parent . get ( node )
228
+ }
229
+
230
+ }
0 commit comments