1
+ function createCell ( ) {
2
+ return {
3
+ parent_i : - 1 ,
4
+ parent_j : - 1 ,
5
+ f : 0.0 ,
6
+ g : 0.0 ,
7
+ h : 0.0 ,
8
+ }
9
+ }
10
+
11
+ function isValid ( grid , row , col ) {
12
+ return ( row >= 0 && row < grid . length && col >= 0 && col < grid [ 0 ] . length && ! grid [ row ] [ col ] . isWall ) ;
13
+ }
14
+
15
+ export function aStarSearch ( grid , startRow , startCol , finRow , finCol , checkboxVal ) {
16
+ let cellDetails = [ ] ;
17
+ let visitedNodesInOrder = [ ] ;
18
+
19
+ for ( let i = 0 ; i < grid . length ; ++ i ) {
20
+ let cell = [ ] ;
21
+
22
+ for ( let j = 0 ; j < grid [ 0 ] . length ; ++ j )
23
+ {
24
+ let newCell = createCell ( ) ;
25
+ newCell . f = Number . MAX_VALUE ;
26
+ newCell . g = Number . MAX_VALUE ;
27
+ newCell . h = Number . MAX_VALUE ;
28
+ cell . push ( newCell ) ;
29
+ }
30
+
31
+ cellDetails . push ( cell ) ;
32
+ }
33
+
34
+ const i = startRow , j = startCol ;
35
+ cellDetails [ i ] [ j ] . f = 0.0 ;
36
+ cellDetails [ i ] [ j ] . g = 0.0 ;
37
+ cellDetails [ i ] [ j ] . h = 0.0 ;
38
+ cellDetails [ i ] [ j ] . parent_i = i ;
39
+ cellDetails [ i ] [ j ] . parent_j = j ;
40
+ let openList = [ ] ;
41
+ openList . push ( [ 0.0 , i , j ] ) ;
42
+ var dirx = [ - 1 , 0 , 0 , 1 ] ;
43
+ var diry = [ 0 , - 1 , 1 , 0 ] ;
44
+
45
+ if ( checkboxVal ) {
46
+ dirx = [ - 1 , 0 , 0 , 1 , - 1 , - 1 , 1 , 1 ] ;
47
+ diry = [ 0 , - 1 , 1 , 0 , - 1 , 1 , - 1 , 1 ] ;
48
+ }
49
+
50
+ while ( openList . length ) {
51
+ let i = openList [ 0 ] [ 1 ] , j = openList [ 0 ] [ 2 ] ;
52
+ openList . shift ( ) ;
53
+ grid [ i ] [ j ] . isVisited = true ;
54
+ let gNew , hNew , fNew ;
55
+ let newLvl = [ ] ;
56
+
57
+ // check all possible directions and update the values
58
+ for ( let idx = 0 ; idx < dirx . length ; ++ idx ) {
59
+ let ii = i + dirx [ idx ] ;
60
+ let jj = j + diry [ idx ] ;
61
+ const withCheckbox = ( idx < 4 || ( idx > 3 && checkboxVal ) ) ;
62
+
63
+ if ( isValid ( grid , ii , jj ) && withCheckbox ) {
64
+ if ( grid [ ii ] [ jj ] . isFinish ) {
65
+ cellDetails [ ii ] [ jj ] . parent_i = i ;
66
+ cellDetails [ ii ] [ jj ] . parent_j = j ;
67
+ grid [ ii ] [ jj ] . previousNode = grid [ i ] [ j ] ;
68
+ if ( newLvl . length ) visitedNodesInOrder . push ( newLvl ) ;
69
+ return visitedNodesInOrder ;
70
+ }
71
+ else if ( ! grid [ ii ] [ jj ] . isVisited ) {
72
+ gNew = cellDetails [ i ] [ j ] . g + 1.0 ;
73
+ if ( idx > 3 && withCheckbox ) gNew += 0.4 ;
74
+ hNew = calculateHValue ( ii , jj , finRow , finCol ) ;
75
+ fNew = gNew + hNew ;
76
+
77
+ if ( cellDetails [ ii ] [ jj ] . f === Number . MAX_VALUE || cellDetails [ ii ] [ jj ] . f > fNew ) {
78
+ openList . push ( [ fNew , ii , jj ] ) ;
79
+ openList . sort ( ( elemA , elemB ) => elemA [ 0 ] - elemB [ 0 ] ) ;
80
+ newLvl . push ( [ ii , jj ] ) ;
81
+ cellDetails [ ii ] [ jj ] . f = fNew ;
82
+ cellDetails [ ii ] [ jj ] . g = gNew ;
83
+ cellDetails [ ii ] [ jj ] . h = hNew ;
84
+ cellDetails [ ii ] [ jj ] . parent_i = i ;
85
+ cellDetails [ ii ] [ jj ] . parent_j = j ;
86
+ grid [ ii ] [ jj ] . previousNode = grid [ i ] [ j ] ;
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ visitedNodesInOrder . push ( newLvl ) ;
93
+ }
94
+
95
+ return visitedNodesInOrder ;
96
+ }
97
+
98
+ // heuristic; approximate distance between current node and finish node
99
+ function calculateHValue ( i , j , finRow , finCol ) {
100
+ return Math . abs ( finRow - i ) + Math . abs ( finCol - j ) ;
101
+ }
0 commit comments