11package io .github .coderodde .pathfinding .finders ;
22
3+ import io .github .coderodde .pathfinding .finders .jps .DiagonalCrossingJumper ;
34import io .github .coderodde .pathfinding .finders .jps .DiagonalCrossingNeighbourFinder ;
45import io .github .coderodde .pathfinding .finders .jps .DiagonalNoCrossingNeighbourFinder ;
6+ import io .github .coderodde .pathfinding .finders .jps .DiagonalNonCrossingJumper ;
7+ import io .github .coderodde .pathfinding .finders .jps .NoDiagonalJumper ;
58import io .github .coderodde .pathfinding .finders .jps .NoDiagonalNeighbourFinder ;
9+ import io .github .coderodde .pathfinding .heuristics .HeuristicFunction ;
610import io .github .coderodde .pathfinding .logic .GridCellNeighbourIterable ;
7- import io .github .coderodde .pathfinding .logic .GridNodeExpander ;
811import io .github .coderodde .pathfinding .logic .PathfindingSettings ;
912import io .github .coderodde .pathfinding .logic .SearchState ;
1013import io .github .coderodde .pathfinding .logic .SearchStatistics ;
1114import io .github .coderodde .pathfinding .model .GridModel ;
1215import io .github .coderodde .pathfinding .utils .Cell ;
1316import io .github .coderodde .pathfinding .utils .CellType ;
14- import java .util .ArrayList ;
1517import java .util .HashMap ;
18+ import java .util .HashSet ;
1619import java .util .List ;
1720import java .util .Map ;
1821import java .util .PriorityQueue ;
1922import java .util .Queue ;
23+ import java .util .Set ;
2024
2125/**
2226 * This class implements the Jump Point Search.
@@ -82,12 +86,21 @@ public List<Cell> findPath(GridModel model,
8286 NeighbourFinder neighbourFinder =
8387 getNeighbourFinder (pathfindingSettings );
8488
89+ Jumper jumper = getJumper (pathfindingSettings );
90+
8591 Cell source = model .getSourceGridCell ();
8692 Cell target = model .getTargetGridCell ();
87- HeapNode startHeapNode = new HeapNode (source , 0.0 );
8893
89- Queue <HeapNode > open = new PriorityQueue <>();
90- Map <Cell , Cell > parentsMap = new HashMap <>();
94+ Queue <HeapNode > open = new PriorityQueue <>();
95+ Set <Cell > openSet = new HashSet <>();
96+ Set <Cell > closed = new HashSet <>();
97+ Map <Cell , Double > distanceMap = new HashMap <>();
98+ Map <Cell , Cell > parentsMap = new HashMap <>();
99+
100+ open .add (new HeapNode (source , 0.0 ));
101+ openSet .add (source );
102+ parentsMap .put (source , null );
103+ distanceMap .put (source , 0.0 );
91104
92105 while (!open .isEmpty ()) {
93106 Cell current = open .remove ().cell ;
@@ -97,21 +110,36 @@ public List<Cell> findPath(GridModel model,
97110 model .setCellType (current , CellType .VISITED );
98111 }
99112
113+ closed .add (current );
114+
100115 if (current .equals (target )) {
101116 return tracebackPath (target ,
102117 parentsMap );
103118 }
104119
105120 identifySuccessors (current ,
121+ open ,
122+ closed ,
123+ openSet ,
124+ distanceMap ,
106125 parentsMap ,
107126 model ,
108127 pathfindingSettings ,
109- neighbourFinder );
128+ neighbourFinder ,
129+ jumper );
110130 }
111131
112132 return List .of ();
113133 }
114134
135+ /**
136+ * Returns the required neighbour finder.
137+ *
138+ * @param pathfindingSettings the pathfinding settings object.
139+ *
140+ * @return an instance of the suitable
141+ * {@link io.github.coderodde.pathfinding.finders.JumpPointSearchFinder.NeighbourFinder}.
142+ */
115143 private static NeighbourFinder
116144 getNeighbourFinder (PathfindingSettings pathfindingSettings ) {
117145
@@ -125,17 +153,92 @@ public List<Cell> findPath(GridModel model,
125153 return new NoDiagonalNeighbourFinder ();
126154 }
127155 }
156+
157+ /**
158+ * Returns the required jumper.
159+ *
160+ * @param pathfindingSettings the pathfinding settings object.
161+ *
162+ * @return an instance of the suitable
163+ * {@link io.github.coderodde.pathfinding.finders.JumpPointSearchFinder.Jumper}.
164+ */
165+ private static Jumper getJumper (PathfindingSettings pathfindingSettings ) {
166+
167+ if (pathfindingSettings .allowDiagonals ()) {
168+ if (pathfindingSettings .dontCrossCorners ()) {
169+ return new DiagonalNonCrossingJumper ();
170+ } else {
171+ return new DiagonalCrossingJumper ();
172+ }
173+ } else {
174+ return new NoDiagonalJumper ();
175+ }
176+ }
128177
129178 private static void identifySuccessors (Cell current ,
179+ Queue <HeapNode > open ,
180+ Set <Cell > closed ,
181+ Set <Cell > openSet ,
182+ Map <Cell , Double > distanceMap ,
130183 Map <Cell , Cell > parentsMap ,
131184 GridModel model ,
132185 PathfindingSettings ps ,
133- NeighbourFinder neighbourFinder ) {
186+ NeighbourFinder neighbourFinder ,
187+ Jumper jumper ) {
134188
135189 List <Cell > neighbors =
136190 neighbourFinder .findNeighbours (current ,
137191 parentsMap ,
138192 model ,
139193 ps );
194+
195+ int x = current .getx ();
196+ int y = current .gety ();
197+ HeuristicFunction hf = ps .getHeuristicFunction ();
198+
199+ for (Cell child : neighbors ) {
200+ Cell jumpCell = jumper .jump (child .getx (),
201+ child .gety (),
202+ x ,
203+ y ,
204+ model );
205+
206+ if (jumpCell == null ) {
207+ continue ;
208+ }
209+
210+ int jx = jumpCell .getx ();
211+ int jy = jumpCell .gety ();
212+ jumpCell = model .getCell (jx , jy );
213+
214+ if (closed .contains (jumpCell )) {
215+ continue ;
216+ }
217+
218+ double distance = hf .estimate (jx - x ,
219+ jy - y );
220+
221+ double nextg = distanceMap .get (current ) + distance ;
222+
223+ if (!openSet .contains (jumpCell ) ||
224+ nextg < distanceMap .get (jumpCell )) {
225+
226+ distanceMap .put (jumpCell , nextg );
227+
228+ double f =
229+ nextg +
230+ hf .estimate (jx - model .getTargetGridCell ().getx (),
231+ jy - model .getTargetGridCell ().gety ());
232+
233+ parentsMap .put (jumpCell , current );
234+
235+
236+ if (!openSet .contains (jumpCell )) {
237+ openSet .add (jumpCell );
238+ }
239+
240+ open .add (new HeapNode (jumpCell , f ));
241+ }
242+ }
140243 }
141244}
0 commit comments