1+ export function mazeSolverSteps ( grid , start , end , allowDiagonal = false ) {
2+ const rows = grid . length ;
3+ const cols = grid [ 0 ] . length ;
4+
5+ const steps = [ ] ;
6+ const visited = Array . from ( { length : rows } , ( ) => Array ( cols ) . fill ( false ) ) ;
7+ const parent = Array . from ( { length : rows } , ( ) =>
8+ Array ( cols ) . fill ( null )
9+ ) ;
10+
11+ const directions = allowDiagonal ? [ [ 0 , 1 ] , [ 1 , 0 ] , [ 0 , - 1 ] , [ - 1 , 0 ] , [ 1 , 1 ] , [ 1 , - 1 ] , [ - 1 , 1 ] , [ - 1 , - 1 ] , ]
12+ : [ [ 0 , 1 ] , [ 1 , 0 ] , [ 0 , - 1 ] , [ - 1 , 0 ] ] ;
13+
14+ const queue = [ ] ;
15+ queue . push ( start ) ;
16+ visited [ start [ 0 ] ] [ start [ 1 ] ] = true ;
17+
18+ let solutionFound = false ;
19+
20+ while ( queue . length > 0 ) {
21+ const [ r , c ] = queue . shift ( ) ;
22+ //exploring cell
23+ steps . push ( { type : "explore" , row : r , col : c , visited : visited . map ( v => [ ...v ] ) ,
24+ grid : cloneGrid ( grid ) ,
25+ message : `Exploring cell (${ r } , ${ c } ).` ,
26+ } ) ;
27+
28+ if ( r === end [ 0 ] && c === end [ 1 ] ) {
29+ solutionFound = true ;
30+ steps . push ( { type : "found" , row : r , col : c , visited : visited . map ( v => [ ...v ] ) ,
31+ grid : cloneGrid ( grid ) ,
32+ message : `Reached end (${ r } , ${ c } ) — shortest path found!` ,
33+ } ) ;
34+ break ;
35+ }
36+
37+ for ( const [ dr , dc ] of directions ) {
38+ const nr = r + dr ;
39+ const nc = c + dc ;
40+
41+ if ( nr >= 0 && nc >= 0 && nr < rows && nc < cols && grid [ nr ] [ nc ] !== 1 && ! visited [ nr ] [ nc ] ) {
42+ visited [ nr ] [ nc ] = true ;
43+ parent [ nr ] [ nc ] = [ r , c ] ;
44+ queue . push ( [ nr , nc ] ) ;
45+
46+ steps . push ( { type : "enqueue" , row : nr , col : nc , visited : visited . map ( v => [ ...v ] ) ,
47+ grid : cloneGrid ( grid ) ,
48+ message : `Adding cell (${ nr } , ${ nc } ) to queue.` ,
49+ } ) ;
50+ }
51+ }
52+ }
53+ //reconstruct shortest path
54+ const path = [ ] ;
55+ if ( solutionFound ) {
56+ let node = end ;
57+ while ( node ) {
58+ path . unshift ( node ) ;
59+ node = parent [ node [ 0 ] ] [ node [ 1 ] ] ;
60+ }
61+
62+ for ( const [ r , c ] of path ) {
63+ steps . push ( { type : "path_cell" , row : r , col : c , visited : visited . map ( v => [ ...v ] ) ,
64+ grid : cloneGrid ( grid ) ,
65+ path : [ ...path ] ,
66+ message : `Cell (${ r } , ${ c } ) is part of the shortest path.` ,
67+ } ) ;
68+ }
69+ } else {
70+ steps . push ( { type : "no_path" , row : null , col : null , visited : visited . map ( v => [ ...v ] ) ,
71+ grid : cloneGrid ( grid ) ,
72+ message : "No path possible between Start and End points." ,
73+ } ) ;
74+ }
75+
76+ return { steps, solutionFound, path} ;
77+ }
78+
79+ function cloneGrid ( grid ) {
80+ return grid . map ( row => [ ...row ] ) ;
81+ }
0 commit comments