9
9
import com .almasb .fxgl .pathfinding .CellState ;
10
10
import com .almasb .fxgl .pathfinding .Pathfinder ;
11
11
12
- import java .util .ArrayList ;
13
- import java .util .Arrays ;
14
- import java .util .Collections ;
15
- import java .util .List ;
16
- import java .util .stream .Collectors ;
12
+ import java .util .*;
17
13
18
14
/**
19
15
* @author Almas Baimagambetov ([email protected] )
@@ -22,6 +18,9 @@ public final class AStarPathfinder implements Pathfinder<AStarCell> {
22
18
23
19
private final AStarGrid grid ;
24
20
21
+ private boolean isCachingPaths = false ;
22
+ private Map <CacheKey , List <AStarCell >> cache = new HashMap <>();
23
+
25
24
public AStarPathfinder (AStarGrid grid ) {
26
25
this .grid = grid ;
27
26
}
@@ -30,6 +29,18 @@ public AStarGrid getGrid() {
30
29
return grid ;
31
30
}
32
31
32
+ /**
33
+ * If set to true, computed paths for same start and end cells are cached.
34
+ * Default is false.
35
+ */
36
+ public void setCachingPaths (boolean isCachingPaths ) {
37
+ this .isCachingPaths = isCachingPaths ;
38
+ }
39
+
40
+ public boolean isCachingPaths () {
41
+ return isCachingPaths ;
42
+ }
43
+
33
44
@ Override
34
45
public List <AStarCell > findPath (int sourceX , int sourceY , int targetX , int targetY ) {
35
46
return findPath (grid .getData (), grid .get (sourceX , sourceY ), grid .get (targetX , targetY ));
@@ -54,6 +65,16 @@ public List<AStarCell> findPath(AStarCell[][] grid, AStarCell start, AStarCell t
54
65
if (start == target || target .getState () == CellState .NOT_WALKABLE )
55
66
return Collections .emptyList ();
56
67
68
+ var cacheKey = new CacheKey (start .getX (), start .getY (), target .getX (), target .getY ());
69
+
70
+ if (isCachingPaths ) {
71
+ var path = cache .get (cacheKey );
72
+
73
+ if (path != null ) {
74
+ return new ArrayList <>(path );
75
+ }
76
+ }
77
+
57
78
// reset grid cells data
58
79
for (int y = 0 ; y < grid [0 ].length ; y ++) {
59
80
for (int x = 0 ; x < grid .length ; x ++) {
@@ -63,8 +84,8 @@ public List<AStarCell> findPath(AStarCell[][] grid, AStarCell start, AStarCell t
63
84
}
64
85
}
65
86
66
- List <AStarCell > open = new ArrayList <>();
67
- List <AStarCell > closed = new ArrayList <>();
87
+ Set <AStarCell > open = new HashSet <>();
88
+ Set <AStarCell > closed = new HashSet <>();
68
89
69
90
AStarCell current = start ;
70
91
@@ -102,17 +123,28 @@ public List<AStarCell> findPath(AStarCell[][] grid, AStarCell start, AStarCell t
102
123
if (open .isEmpty ())
103
124
return Collections .emptyList ();
104
125
105
- AStarCell acc = open . get ( 0 ) ;
126
+ AStarCell acc = null ;
106
127
107
128
for (AStarCell a : open ) {
129
+ if (acc == null ) {
130
+ acc = a ;
131
+ continue ;
132
+ }
133
+
108
134
acc = a .getFCost () < acc .getFCost () ? a : acc ;
109
135
}
110
136
111
137
current = acc ;
112
138
}
113
139
}
114
140
115
- return buildPath (start , target );
141
+ var path = buildPath (start , target );
142
+
143
+ if (isCachingPaths ) {
144
+ cache .put (cacheKey , path );
145
+ }
146
+
147
+ return new ArrayList <>(path );
116
148
}
117
149
118
150
private List <AStarCell > buildPath (AStarCell start , AStarCell target ) {
@@ -133,11 +165,10 @@ private List<AStarCell> buildPath(AStarCell start, AStarCell target) {
133
165
* @param busyNodes nodes which are busy, i.e. walkable but have a temporary obstacle
134
166
* @return neighbors of the node
135
167
*/
136
- protected List <AStarCell > getValidNeighbors (AStarCell node , AStarCell ... busyNodes ) {
137
- var busyNodesList = Arrays .asList (busyNodes );
138
- return grid .getNeighbors (node .getX (), node .getY ()).stream ()
139
- .filter (AStarCell ::isWalkable )
140
- .filter (neighbor -> !busyNodesList .contains (neighbor ))
141
- .collect (Collectors .toList ());
168
+ private List <AStarCell > getValidNeighbors (AStarCell node , AStarCell ... busyNodes ) {
169
+ var result = grid .getNeighbors (node .getX (), node .getY ());
170
+ result .removeAll (Arrays .asList (busyNodes ));
171
+ result .removeIf (cell -> !cell .isWalkable ());
172
+ return result ;
142
173
}
143
174
}
0 commit comments