(svn r5066) -Feature: [YAPF] Train selects the best station platform by length

This commit is contained in:
KUDr 2006-06-01 21:39:35 +00:00
parent 76a8f036df
commit bd25f49d3f
7 changed files with 75 additions and 11 deletions

View File

@ -1407,6 +1407,9 @@ const SettingDesc _patch_settings[] = {
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p0 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 500 , -1000000, 1000000, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p1 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, -100 , -1000000, 1000000, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p2 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 5 , -1000000, 1000000, STR_NULL, NULL),
// penalties for too long or too short station platforms (TODO: NS flag or higher revision?)
SDT_CONDVAR (Patches, yapf.rail_longer_platform_penalty, SLE_UINT, 28, SL_MAX_VERSION,NS, 0, 10 * YAPF_TILE_LENGTH, 0, 20000, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_shorter_platform_penalty, SLE_UINT, 28, SL_MAX_VERSION,NS, 0, 100 * YAPF_TILE_LENGTH, 0, 20000, STR_NULL, NULL),
SDT_END()
};

View File

@ -27,8 +27,8 @@ struct CFollowTrackT : public FollowTrack_t
m_new_tile = INVALID_TILE;
m_new_td_bits = TRACKDIR_BIT_NONE;
m_exitdir = INVALID_DIAGDIR;
m_is_tunnel = false;
m_tunnel_tiles_skipped = 0;
m_is_station = m_is_tunnel = false;
m_tiles_skipped = 0;
}
FORCEINLINE static TransportType TT() {return Ttr_type_;}
@ -57,7 +57,7 @@ struct CFollowTrackT : public FollowTrack_t
}
protected:
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tunnel_tiles_skipped */
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
FORCEINLINE void FollowTileExit()
{
// extra handling for tunnels in our direction
@ -68,17 +68,27 @@ protected:
FindLengthOfTunnelResult flotr = FindLengthOfTunnel(m_old_tile, m_exitdir);
m_new_tile = flotr.tile;
m_is_tunnel = true;
m_tunnel_tiles_skipped = flotr.length - 1;
m_tiles_skipped = flotr.length - 1;
return;
}
assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
}
// not a tunnel
// not a tunnel or station
m_is_tunnel = false;
m_tunnel_tiles_skipped = 0;
// normal tile
m_tiles_skipped = 0;
// normal or station tile
TileIndexDiff diff = TileOffsByDir(m_exitdir);
m_new_tile = TILE_ADD(m_old_tile, diff);
// special handling for stations
if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
m_is_station = true;
} else if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
m_is_station = true;
} else {
m_is_station = false;
}
}
/** stores track status (available trackdirs) for the new tile into m_new_td_bits */
@ -171,6 +181,21 @@ protected:
if (tunnel_enterdir != m_exitdir)
return false;
}
// special handling for rail stations - get to the end of platform
if (IsRailTT() && m_is_station) {
// entered railway station
// get platform length
uint length = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td));
// how big step we must do to get to the last platform tile;
m_tiles_skipped = length - 1;
// move to the platform end
TileIndexDiff diff = TileOffsByDir(m_exitdir);
diff *= m_tiles_skipped;
m_new_tile = TILE_ADD(m_new_tile, diff);
return true;
}
return true;
}
@ -184,7 +209,7 @@ protected:
m_new_tile = m_old_tile;
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
m_exitdir = exitdir;
m_tunnel_tiles_skipped = 0;
m_tiles_skipped = 0;
m_is_tunnel = false;
return true;
}

View File

@ -37,7 +37,8 @@ typedef struct FollowTrack_t
// TrackdirBits m_red_td_bits;
DiagDirection m_exitdir;
bool m_is_tunnel;
int m_tunnel_tiles_skipped;
bool m_is_station;
int m_tiles_skipped;
} FollowTrack_t;
/** track followers */

View File

@ -13,6 +13,7 @@ EXTERN_C_BEGIN
#include "../tunnel_map.h"
#include "../bridge_map.h"
#include "../bridge.h"
#include "../station.h"
#include "../station_map.h"
#include "../vehicle.h"
#include "../variables.h"

View File

@ -138,6 +138,24 @@ public:
return cost;
}
FORCEINLINE int PlatformLengthPenalty(int platform_length)
{
int cost = 0;
const Vehicle* v = Yapf().GetVehicle();
assert(v != NULL);
assert(v->type == VEH_Train);
assert(v->u.rail.cached_total_length != 0);
int needed_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE;
if (platform_length > needed_platform_length) {
// apply penalty for longer platform than needed
cost += Yapf().PfGetSettings().rail_longer_platform_penalty * (platform_length - needed_platform_length);
} else {
// apply penalty for shorter platform than needed
cost += Yapf().PfGetSettings().rail_shorter_platform_penalty * (needed_platform_length - platform_length);
}
return cost;
}
public:
FORCEINLINE void SetMaxCost(int max_cost) {m_max_cost = max_cost;}
@ -245,7 +263,20 @@ public:
}
// if we skipped some tunnel tiles, add their cost
segment_cost += YAPF_TILE_LENGTH * F.m_tunnel_tiles_skipped;
segment_cost += YAPF_TILE_LENGTH * F.m_tiles_skipped;
// add penalty for skipped station tiles
if (F.m_is_station)
{
if (target_seen) {
// it is our destination station
uint platform_length = F.m_tiles_skipped + 1;
segment_cost += PlatformLengthPenalty(platform_length);
} else {
// station is not our destination station, apply penalty for skipped platform tiles
segment_cost += Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped;
}
}
// add min/max speed penalties
int min_speed = 0;

View File

@ -89,7 +89,7 @@ public:
if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false;
// if we skipped some tunnel tiles, add their cost
segment_cost += 10 * F.m_tunnel_tiles_skipped;
segment_cost += 10 * F.m_tiles_skipped;
// add hilly terrain penalty
segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir);

View File

@ -51,6 +51,9 @@ YS_DEF_BEGIN
YS_DEF(int32 , rail_look_ahead_signal_p0) ///< constant in polynomial penalty function
YS_DEF(int32 , rail_look_ahead_signal_p1) ///< constant in polynomial penalty function
YS_DEF(int32 , rail_look_ahead_signal_p2) ///< constant in polynomial penalty function
YS_DEF(uint32, rail_longer_platform_penalty) ///< penalty for longer station platform than train
YS_DEF(uint32, rail_shorter_platform_penalty) ///< penalty for shorter station platform than train
YS_DEF_END;
#undef YS_DEF_BEGIN