From 0f3d06ba75f86c71003be8babc334495c3831b4d Mon Sep 17 00:00:00 2001 From: megalord397 Date: Sat, 18 Jul 2020 14:39:05 +0300 Subject: [PATCH 1/5] add feature for search closest path --- jps.hh | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/jps.hh b/jps.hh index 6a76d86..1f8d180 100644 --- a/jps.hh +++ b/jps.hh @@ -283,6 +283,9 @@ enum JPS_Flags_ // Don't check whether end position is walkable. JPS_Flag_NoEndCheck = 0x08, + + // Find closest path + JPS_Flag_Closest = 0x16, }; enum JPS_Result @@ -896,6 +899,8 @@ public: private: const GRID& grid; + Position closestPosition; + unsigned closestBestDistance; Node *getNode(const Position& pos); bool identifySuccessors(const Node& n); @@ -1291,9 +1296,15 @@ template template bool Searcher::findPath(PV& case JPS_EMPTY_PATH: JPS_ASSERT(false); // can't happen // fall through - case JPS_NO_PATH: case JPS_OUT_OF_MEMORY: return false; + case JPS_NO_PATH: + if(flags & JPS_Flag_Closest) + { + res = findPathInit(start, closestPosition, flags); + continue; + } + return false; } } } @@ -1305,6 +1316,8 @@ template JPS_Result Searcher::findPathInit(Position start, this->flags = flags; endPos = end; + closestBestDistance = M_MAX_UNSIGNED; + closestPosition = start; // FIXME: check this if(start == end && !(flags & (JPS_Flag_NoStartCheck|JPS_Flag_NoEndCheck))) @@ -1318,11 +1331,15 @@ template JPS_Result Searcher::findPathInit(Position start, if(!grid(start.x, start.y)) return JPS_NO_PATH; - if(!(flags & JPS_Flag_NoEndCheck)) + if(!(flags & (JPS_Flag_NoEndCheck | JPS_Flag_Closest))) if(!grid(end.x, end.y)) return JPS_NO_PATH; - Node *endNode = getNode(end); // this might realloc the internal storage... + Node *endNode = NULL; + if(flags & JPS_Flag_NoEndCheck) + endNode = nodemap(end.x, end.y); + else + endNode = getNode(end); // this might realloc the internal storage... if(!endNode) return JPS_OUT_OF_MEMORY; endNodeIdx = storage.getindex(endNode); // .. so we keep this for later @@ -1353,6 +1370,20 @@ template JPS_Result Searcher::findPathStep(int limit) return JPS_NO_PATH; Node& n = open.popNode(); n.setClosed(); + if(closestBestDistance == M_MAX_UNSIGNED) + { + closestPosition = n.pos; + closestBestDistance = Heuristic::Manhattan(n.pos, endPos); + } + else + { + unsigned h = Heuristic::Manhattan(n.pos, endPos); + if(closestBestDistance > h) + { + closestBestDistance = h; + closestPosition = n.pos; + } + } if(n.pos == endPos) return JPS_FOUND_PATH; if(!identifySuccessors(n)) From 77c1574f68a6d1663770850299090dfbb5b43345 Mon Sep 17 00:00:00 2001 From: megalord397 Date: Sat, 18 Jul 2020 16:19:56 +0300 Subject: [PATCH 2/5] fix case when start equal end --- jps.hh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jps.hh b/jps.hh index 1f8d180..8ab0eda 100644 --- a/jps.hh +++ b/jps.hh @@ -1301,8 +1301,11 @@ template template bool Searcher::findPath(PV& case JPS_NO_PATH: if(flags & JPS_Flag_Closest) { - res = findPathInit(start, closestPosition, flags); - continue; + if (start != closestPosition) + { + res = findPathInit(start, closestPosition, flags); + continue; + } } return false; } From f103f05aea5b19d1628dbf2856630483588a8804 Mon Sep 17 00:00:00 2001 From: megalord397 Date: Mon, 20 Jul 2020 11:10:14 +0300 Subject: [PATCH 3/5] fix types --- jps.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jps.hh b/jps.hh index 8ab0eda..03660ac 100644 --- a/jps.hh +++ b/jps.hh @@ -900,7 +900,7 @@ private: const GRID& grid; Position closestPosition; - unsigned closestBestDistance; + ScoreType closestBestDistance; Node *getNode(const Position& pos); bool identifySuccessors(const Node& n); @@ -1319,7 +1319,7 @@ template JPS_Result Searcher::findPathInit(Position start, this->flags = flags; endPos = end; - closestBestDistance = M_MAX_UNSIGNED; + closestBestDistance = UINT_MAX; closestPosition = start; // FIXME: check this From c5095e0a7047733745ee9fe43f2a25ca7d3da66e Mon Sep 17 00:00:00 2001 From: megalord397 Date: Mon, 20 Jul 2020 11:15:26 +0300 Subject: [PATCH 4/5] skip calculation of closest point if full path is needed --- jps.hh | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/jps.hh b/jps.hh index 03660ac..b4142b4 100644 --- a/jps.hh +++ b/jps.hh @@ -1373,18 +1373,21 @@ template JPS_Result Searcher::findPathStep(int limit) return JPS_NO_PATH; Node& n = open.popNode(); n.setClosed(); - if(closestBestDistance == M_MAX_UNSIGNED) + if(flags & JPS_Flag_Closest) { - closestPosition = n.pos; - closestBestDistance = Heuristic::Manhattan(n.pos, endPos); - } - else - { - unsigned h = Heuristic::Manhattan(n.pos, endPos); - if(closestBestDistance > h) + if(closestBestDistance == M_MAX_UNSIGNED) { - closestBestDistance = h; closestPosition = n.pos; + closestBestDistance = Heuristic::Manhattan(n.pos, endPos); + } + else + { + unsigned h = Heuristic::Manhattan(n.pos, endPos); + if(closestBestDistance > h) + { + closestBestDistance = h; + closestPosition = n.pos; + } } } if(n.pos == endPos) From 642736f97e3c0bcf3c485dd60c8d05b5131c0036 Mon Sep 17 00:00:00 2001 From: megalord397 Date: Mon, 20 Jul 2020 11:23:16 +0300 Subject: [PATCH 5/5] generate path from last search --- jps.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jps.hh b/jps.hh index b4142b4..757dd52 100644 --- a/jps.hh +++ b/jps.hh @@ -1303,8 +1303,8 @@ template template bool Searcher::findPath(PV& { if (start != closestPosition) { - res = findPathInit(start, closestPosition, flags); - continue; + endNodeIdx = storage.getindex(getNode(closestPosition)); + return findPathFinish(path, step) == JPS_FOUND_PATH; } } return false;