From 4d9027a2a50bca085e8b9a009fa542e0b74181fa Mon Sep 17 00:00:00 2001 From: Yourself Date: Fri, 15 Nov 2019 18:38:26 -0800 Subject: [PATCH 1/2] RV PF penalizes vehicles destined for same stop --- src/pathfinder/yapf/yapf_road.cpp | 66 +++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 99ebc92235..1fb8f96f7d 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -11,6 +11,7 @@ #include "yapf.hpp" #include "yapf_node_road.hpp" #include "../../roadstop_base.h" +#include "../../vehicle_func.h" #include "../../safeguards.h" @@ -23,6 +24,8 @@ */ const uint MAX_RV_PF_TILES = 1 << 11; +const int MAX_TARGETS = 4; + template class CYapfCostRoadT { @@ -68,6 +71,15 @@ protected: inline int OneTileCost(TileIndex tile, Trackdir trackdir) { int cost = 0; + + bool predictedOccupied = false; + for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != 0xFFFF; ++i) { + if (Yapf().leaderTargets[i] != tile) continue; + cost += Yapf().PfGetSettings().road_curve_penalty; + predictedOccupied = true; + break; + } + /* set base cost */ if (IsDiagonalTrackdir(trackdir)) { cost += YAPF_TILE_LENGTH; @@ -91,10 +103,18 @@ protected: const RoadStop::Entry *entry = rs->GetEntry(dir); cost += entry->GetOccupied() * Yapf().PfGetSettings().road_stop_occupied_penalty / entry->GetLength(); } + + if (predictedOccupied) { + cost += Yapf().PfGetSettings().road_stop_occupied_penalty; + } } else { /* Increase cost for filled road stops */ cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty * (!rs->IsFreeBay(0) + !rs->IsFreeBay(1)) / 2; + if (predictedOccupied) { + cost += Yapf().PfGetSettings().road_stop_bay_occupied_penalty; + } } + break; } @@ -326,7 +346,31 @@ public: } }; +struct FindVehiclesOnTileProcData { + const Vehicle *originVehicle; + TileIndex (*targets)[MAX_TARGETS]; +}; +static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) +{ + FindVehiclesOnTileProcData *data = (FindVehiclesOnTileProcData*)(_data); + + if (data->originVehicle == v) + return nullptr; + + TileIndex ti = v->tile + TileOffsByDir(v->direction); + + for (int i = 0; i < MAX_TARGETS; i++) { + if ((*data->targets)[i] == 0xFFFF) { + (*data->targets)[i] = ti; + break; + } + if ((*data->targets)[i] == ti) + return nullptr; + } + + return nullptr; +} template class CYapfFollowRoadT @@ -391,6 +435,15 @@ public: /* set origin and destination nodes */ Yapf().SetOrigin(src_tile, src_trackdirs); Yapf().SetDestination(v); + + for (int i = 0; i < MAX_TARGETS; ++i) { + Yapf().leaderTargets[i] = 0xFFFF; + } + FindVehiclesOnTileProcData data; + data.originVehicle = v; + data.targets = &Yapf().leaderTargets; + TileIndex ti = v->tile + TileOffsByDir(v->direction); + FindVehicleOnPos(ti, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v); @@ -537,11 +590,16 @@ struct CYapfRoad_TypesT typedef CYapfCostRoadT PfCost; }; -struct CYapfRoad1 : CYapfT > {}; -struct CYapfRoad2 : CYapfT > {}; +template +struct CYapfRoadCommon : CYapfT { + TileIndex leaderTargets[MAX_TARGETS]; ///< the tiles targeted by vehicles in front of the current vehicle +}; -struct CYapfRoadAnyDepot1 : CYapfT > {}; -struct CYapfRoadAnyDepot2 : CYapfT > {}; +struct CYapfRoad1 : CYapfRoadCommon > {}; +struct CYapfRoad2 : CYapfRoadCommon > {}; + +struct CYapfRoadAnyDepot1 : CYapfRoadCommon > {}; +struct CYapfRoadAnyDepot2 : CYapfRoadCommon > {}; Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache) From 2935c6d036e2fbb1edd6ac38c33a3746136352e6 Mon Sep 17 00:00:00 2001 From: Yourself Date: Thu, 21 Nov 2019 19:43:18 -0800 Subject: [PATCH 2/2] Fix: Code quality Use INVALID_TILE instead of 0xFFFF Don't recompute next vehicle tile --- src/pathfinder/yapf/yapf_road.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 1fb8f96f7d..1661c5e7d2 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -73,7 +73,7 @@ protected: int cost = 0; bool predictedOccupied = false; - for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != 0xFFFF; ++i) { + for (int i = 0; i < MAX_TARGETS && Yapf().leaderTargets[i] != INVALID_TILE; ++i) { if (Yapf().leaderTargets[i] != tile) continue; cost += Yapf().PfGetSettings().road_curve_penalty; predictedOccupied = true; @@ -361,7 +361,7 @@ static Vehicle * FindVehiclesOnTileProc(Vehicle *v, void *_data) TileIndex ti = v->tile + TileOffsByDir(v->direction); for (int i = 0; i < MAX_TARGETS; i++) { - if ((*data->targets)[i] == 0xFFFF) { + if ((*data->targets)[i] == INVALID_TILE) { (*data->targets)[i] = ti; break; } @@ -437,13 +437,12 @@ public: Yapf().SetDestination(v); for (int i = 0; i < MAX_TARGETS; ++i) { - Yapf().leaderTargets[i] = 0xFFFF; + Yapf().leaderTargets[i] = INVALID_TILE; } FindVehiclesOnTileProcData data; data.originVehicle = v; data.targets = &Yapf().leaderTargets; - TileIndex ti = v->tile + TileOffsByDir(v->direction); - FindVehicleOnPos(ti, &data, &FindVehiclesOnTileProc); + FindVehicleOnPos(tile, &data, &FindVehiclesOnTileProc); /* find the best path */ path_found = Yapf().FindPath(v);