summaryrefslogtreecommitdiff
path: root/src/pathfinder
diff options
context:
space:
mode:
authorPeter Nelson <peter1138@openttd.org>2019-01-14 23:33:42 +0000
committerPeterN <peter@fuzzle.org>2019-01-19 23:11:17 +0000
commit81330b8d6edee68c38717462737fbfca6420701d (patch)
treeed4e0e34930a5e6f28b5d275c27f6ccb50a2ba63 /src/pathfinder
parent1c725fce47d60907bbf2224c7bdc28607fcf6017 (diff)
downloadopenttd-81330b8d6edee68c38717462737fbfca6420701d.tar.xz
Change: Add path cache for ships.
Diffstat (limited to 'src/pathfinder')
-rw-r--r--src/pathfinder/pathfinder_type.h3
-rw-r--r--src/pathfinder/yapf/yapf.h3
-rw-r--r--src/pathfinder/yapf/yapf_ship.cpp18
3 files changed, 19 insertions, 5 deletions
diff --git a/src/pathfinder/pathfinder_type.h b/src/pathfinder/pathfinder_type.h
index 73031d5c8..0ecf00bbd 100644
--- a/src/pathfinder/pathfinder_type.h
+++ b/src/pathfinder/pathfinder_type.h
@@ -40,6 +40,9 @@ static const int YAPF_TILE_CORNER_LENGTH = 71;
*/
static const int YAPF_INFINITE_PENALTY = 1000 * YAPF_TILE_LENGTH;
+/** Maximum length of ship path cache */
+static const int YAPF_SHIP_PATH_CACHE_LENGTH = 32;
+
/**
* Helper container to find a depot
*/
diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h
index 00eb7e562..84bd35c8b 100644
--- a/src/pathfinder/yapf/yapf.h
+++ b/src/pathfinder/yapf/yapf.h
@@ -15,6 +15,7 @@
#include "../../direction_type.h"
#include "../../track_type.h"
#include "../../vehicle_type.h"
+#include "../../ship.h"
#include "../pathfinder_type.h"
/**
@@ -26,7 +27,7 @@
* @param path_found [out] Whether a path has been found (true) or has been guessed (false)
* @return the best trackdir for next turn or INVALID_TRACK if the path could not be found
*/
-Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found);
+Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache);
/**
* Returns true if it is better to reverse the ship before leaving depot using YAPF.
diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp
index 44a5c0cfa..7ca95ae69 100644
--- a/src/pathfinder/yapf/yapf_ship.cpp
+++ b/src/pathfinder/yapf/yapf_ship.cpp
@@ -54,7 +54,7 @@ public:
return 'w';
}
- static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
+ static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache)
{
/* handle special case - when next tile is destination tile */
if (tile == v->dest_tile) {
@@ -90,9 +90,17 @@ public:
Node *pNode = pf.GetBestNode();
if (pNode != NULL) {
+ uint steps = 0;
+ for (Node *n = pNode; n->m_parent != NULL; n = n->m_parent) steps++;
+
/* walk through the path back to the origin */
Node *pPrevNode = NULL;
while (pNode->m_parent != NULL) {
+ if (steps > 1 && --steps < YAPF_SHIP_PATH_CACHE_LENGTH) {
+ TrackdirByte td;
+ td = pNode->GetTrackdir();
+ path_cache.push_front(td);
+ }
pPrevNode = pNode;
pNode = pNode->m_parent;
}
@@ -100,6 +108,8 @@ public:
Node &best_next_node = *pPrevNode;
assert(best_next_node.GetTile() == tile);
next_trackdir = best_next_node.GetTrackdir();
+ /* remove last element for the special case when tile == dest_tile */
+ if (path_found && !path_cache.empty()) path_cache.pop_back();
}
return next_trackdir;
}
@@ -222,10 +232,10 @@ struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , C
struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {};
/** Ship controller helper - path finder invoker */
-Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
+Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache)
{
/* default is YAPF type 2 */
- typedef Trackdir (*PfnChooseShipTrack)(const Ship*, TileIndex, DiagDirection, TrackBits, bool &path_found);
+ typedef Trackdir (*PfnChooseShipTrack)(const Ship*, TileIndex, DiagDirection, TrackBits, bool &path_found, ShipPathCache &path_cache);
PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir, allow 90-deg
/* check if non-default YAPF type needed */
@@ -235,7 +245,7 @@ Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir,
pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir, allow 90-deg
}
- Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found);
+ Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found, path_cache);
return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;
}