Changeset - r9799:6ed239f36eea
[Not reviewed]
master
0 4 0
rubidium - 16 years ago 2008-08-02 22:51:07
rubidium@openttd.org
(svn r13941) -Codechange [YAPP]: Added YAPP-related penalties to YAPF. (michi_cc)
4 files changed with 82 insertions and 40 deletions:
0 comments (0 inline, 0 general)
src/settings.cpp
Show inline comments
 
@@ -1716,24 +1716,26 @@ const SettingDesc _patch_settings[] = {
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_exit_penalty,              SLE_UINT, 28, SL_MAX_VERSION, 0, 0,   100 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_station_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    30 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_slope_penalty,                     SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve45_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve90_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     6 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_depot_reverse_penalty,             SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    50 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_crossing_penalty,                  SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_max_signals,            SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10,                     1,     100, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p0,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,   500,              -1000000, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p1,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,  -100,              -1000000, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p2,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,     5,              -1000000, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_pbs_cross_penalty,                 SLE_UINT,100, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_pbs_signal_back_penalty,           SLE_UINT,100, SL_MAX_VERSION, 0, 0,    15 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_longer_platform_penalty,           SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_longer_platform_per_tile_penalty,  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_shorter_platform_penalty,          SLE_UINT, 33, SL_MAX_VERSION, 0, 0,    40 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.rail_shorter_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.road_slope_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.road_curve_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.road_crossing_penalty,                  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
	 SDT_CONDVAR(GameSettings, pf.yapf.road_stop_penalty,                      SLE_UINT, 47, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 

	
 
	 SDT_CONDVAR(GameSettings, game_creation.land_generator,                  SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       1, 0, STR_CONFIG_PATCHES_LAND_GENERATOR,        NULL),
 
	 SDT_CONDVAR(GameSettings, game_creation.oil_refinery_limit,              SLE_UINT8, 30, SL_MAX_VERSION, 0, 0,    32,                    12,      48, 0, STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE, NULL),
 
	 SDT_CONDVAR(GameSettings, game_creation.tgen_smoothness,                 SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       3, 0, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN,  NULL),
src/settings_type.h
Show inline comments
 
@@ -209,24 +209,26 @@ struct YAPFSettings {
 
	uint32 rail_lastred_penalty;             ///< penalty for last red signal
 
	uint32 rail_lastred_exit_penalty;        ///< penalty for last red exit signal
 
	uint32 rail_station_penalty;             ///< penalty for non-target station tile
 
	uint32 rail_slope_penalty;               ///< penalty for up-hill slope
 
	uint32 rail_curve45_penalty;             ///< penalty for curve
 
	uint32 rail_curve90_penalty;             ///< penalty for 90-deg curve
 
	uint32 rail_depot_reverse_penalty;       ///< penalty for reversing in the depot
 
	uint32 rail_crossing_penalty;            ///< penalty for level crossing
 
	uint32 rail_look_ahead_max_signals;      ///< max. number of signals taken into consideration in look-ahead load balancer
 
	int32  rail_look_ahead_signal_p0;        ///< constant in polynomial penalty function
 
	int32  rail_look_ahead_signal_p1;        ///< constant in polynomial penalty function
 
	int32  rail_look_ahead_signal_p2;        ///< constant in polynomial penalty function
 
	uint32 rail_pbs_cross_penalty;           ///< penalty for crossing a reserved tile
 
	uint32 rail_pbs_signal_back_penalty;     ///< penalty for passing a pbs signal from the backside
 

	
 
	uint32 rail_longer_platform_penalty;           ///< penalty for longer  station platform than train
 
	uint32 rail_longer_platform_per_tile_penalty;  ///< penalty for longer  station platform than train (per tile)
 
	uint32 rail_shorter_platform_penalty;          ///< penalty for shorter station platform than train
 
	uint32 rail_shorter_platform_per_tile_penalty; ///< penalty for shorter station platform than train (per tile)
 
};
 

	
 
/** Settings related to all pathfinders. */
 
struct PathfinderSettings {
 
	uint8  pathfinder_for_trains;            ///< the pathfinder to use for trains
 
	uint8  pathfinder_for_roadvehs;          ///< the pathfinder to use for roadvehicles
 
	uint8  pathfinder_for_ships;             ///< the pathfinder to use for ships
src/track_func.h
Show inline comments
 
@@ -581,24 +581,37 @@ static inline bool IsDiagonalTrackdir(Tr
 
 */
 
static inline bool TracksOverlap(TrackBits bits)
 
{
 
	/* With no, or only one track, there is no overlap */
 
	if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
 
	/* We know that there are at least two tracks present. When there are more
 
	 * than 2 tracks, they will surely overlap. When there are two, they will
 
	 * always overlap unless they are lower & upper or right & left. */
 
	return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
 
}
 

	
 
/**
 
 * Check if a given track is contained within or overlaps some other tracks.
 
 *
 
 * @param tracks Tracks to be testet against
 
 * @param track The track to test
 
 * @return true if the track is already in the tracks or overlaps the tracks.
 
 */
 
static inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
 
{
 
	if (HasBit(tracks, track)) return true;
 
	return TracksOverlap(tracks | TrackToTrackBits(track));
 
}
 

	
 
/**
 
 * Checks whether the trackdir means that we are reversing.
 
 * @param dir the trackdir to check
 
 * @return true if it is a reversing road trackdir
 
 */
 
static inline bool IsReversingRoadTrackdir(Trackdir dir)
 
{
 
	return (dir & 0x07) >= 6;
 
}
 

	
 
/**
 
 * Checks whether the given trackdir is a straight road
 
 * @param dir the trackdir to check
src/yapf/yapf_costrail.hpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file yapf_costrail.hpp Cost determination for rails. */
 

	
 
#ifndef  YAPF_COSTRAIL_HPP
 
#define  YAPF_COSTRAIL_HPP
 

	
 
#include "../pbs.h"
 

	
 
template <class Types>
 
class CYapfCostRailT
 
	: public CYapfCostBase
 
	, public CostRailSettings
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;               ///< key to hash tables
 
	typedef typename Node::CachedData CachedData;
 
@@ -119,79 +120,100 @@ public:
 
					break;
 

	
 
				default:
 
					break;
 
			}
 
		} else {
 
			// non-diagonal trackdir
 
			cost = YAPF_TILE_CORNER_LENGTH;
 
		}
 
		return cost;
 
	}
 

	
 
	/** The cost for reserved tiles, including skipped ones. */
 
	FORCEINLINE int ReservationCost(Node& n, TileIndex& tile, Trackdir trackdir, int skipped)
 
	{
 
		if (n.m_num_signals_passed >= m_sig_look_ahead_costs.Size() / 2) return 0;
 

	
 
		if (TrackOverlapsTracks(GetReservedTrackbits(tile), TrackdirToTrack(trackdir))) {
 
			int cost = Yapf().PfGetSettings().rail_pbs_cross_penalty;
 
			if (!IsDiagonalTrackdir(trackdir)) cost = (cost * YAPF_TILE_CORNER_LENGTH) / YAPF_TILE_LENGTH;
 
			return cost * (skipped + 1);
 
		}
 
		return 0;
 
	}
 

	
 
	int SignalCost(Node& n, TileIndex tile, Trackdir trackdir)
 
	{
 
		int cost = 0;
 
		// if there is one-way signal in the opposite direction, then it is not our way
 
		CPerfStart perf_cost(Yapf().m_perf_other_cost);
 
		if (IsTileType(tile, MP_RAILWAY)) {
 
			bool has_signal_against = HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir));
 
			bool has_signal_along = HasSignalOnTrackdir(tile, trackdir);
 
			if (has_signal_against && !has_signal_along && IsOnewaySignal(tile, TrackdirToTrack(trackdir))) {
 
				// one-way signal in opposite direction
 
				n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
 
			} else if (has_signal_along) {
 
				SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir);
 
				// cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is
 
				int look_ahead_cost = (n.m_num_signals_passed < m_sig_look_ahead_costs.Size()) ? m_sig_look_ahead_costs.Data()[n.m_num_signals_passed] : 0;
 
				if (sig_state != SIGNAL_STATE_RED) {
 
					// green signal
 
					n.flags_u.flags_s.m_last_signal_was_red = false;
 
					// negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal
 
					if (look_ahead_cost < 0) {
 
						// add its negation to the cost
 
						cost -= look_ahead_cost;
 
					}
 
				} else {
 
					// we have a red signal in our direction
 
					// was it first signal which is two-way?
 
					if (Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.m_choice_seen && has_signal_against && n.m_num_signals_passed == 0) {
 
						// yes, the first signal is two-way red signal => DEAD END
 
						n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
 
						Yapf().m_stopped_on_first_two_way_signal = true;
 
						return -1;
 
					}
 
					SignalType sig_type = GetSignalType(tile, TrackdirToTrack(trackdir));
 
					n.m_last_red_signal_type = sig_type;
 
					n.flags_u.flags_s.m_last_signal_was_red = true;
 
			} else {
 
				if (has_signal_along) {
 
					SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir);
 
					// cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is
 
					int look_ahead_cost = (n.m_num_signals_passed < m_sig_look_ahead_costs.Size()) ? m_sig_look_ahead_costs.Data()[n.m_num_signals_passed] : 0;
 
					if (sig_state != SIGNAL_STATE_RED) {
 
						// green signal
 
						n.flags_u.flags_s.m_last_signal_was_red = false;
 
						// negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal
 
						if (look_ahead_cost < 0) {
 
							// add its negation to the cost
 
							cost -= look_ahead_cost;
 
						}
 
					} else {
 
						SignalType sig_type = GetSignalType(tile, TrackdirToTrack(trackdir));
 
						// we have a red signal in our direction
 
						// was it first signal which is two-way?
 
						if (!IsPbsSignal(sig_type) && Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.m_choice_seen && has_signal_against && n.m_num_signals_passed == 0) {
 
							// yes, the first signal is two-way red signal => DEAD END
 
							n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
 
							Yapf().m_stopped_on_first_two_way_signal = true;
 
							return -1;
 
						}
 
						n.m_last_red_signal_type = sig_type;
 
						n.flags_u.flags_s.m_last_signal_was_red = true;
 

	
 
					// look-ahead signal penalty
 
					if (look_ahead_cost > 0) {
 
						// add the look ahead penalty only if it is positive
 
						cost += look_ahead_cost;
 
						// look-ahead signal penalty
 
						if (!IsPbsSignal(sig_type) && look_ahead_cost > 0) {
 
							// add the look ahead penalty only if it is positive
 
							cost += look_ahead_cost;
 
						}
 

	
 
						// special signal penalties
 
						if (n.m_num_signals_passed == 0) {
 
							switch (sig_type) {
 
								case SIGTYPE_COMBO:
 
								case SIGTYPE_EXIT:   cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit
 
								case SIGTYPE_NORMAL:
 
								case SIGTYPE_ENTRY:  cost += Yapf().PfGetSettings().rail_firstred_penalty; break;
 
								default: break;
 
							};
 
						}
 
					}
 

	
 
					// special signal penalties
 
					if (n.m_num_signals_passed == 0) {
 
						switch (sig_type) {
 
							case SIGTYPE_COMBO:
 
							case SIGTYPE_EXIT:   cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit
 
							case SIGTYPE_NORMAL:
 
							case SIGTYPE_ENTRY:  cost += Yapf().PfGetSettings().rail_firstred_penalty; break;
 
						};
 
					}
 
					n.m_num_signals_passed++;
 
					n.m_segment->m_last_signal_tile = tile;
 
					n.m_segment->m_last_signal_td = trackdir;
 
				}
 
				n.m_num_signals_passed++;
 
				n.m_segment->m_last_signal_tile = tile;
 
				n.m_segment->m_last_signal_td = trackdir;
 

	
 
				if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) {
 
					cost += n.m_num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0;
 
				}
 
			}
 
		}
 
		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);
 
@@ -318,24 +340,27 @@ public:
 

	
 
no_entry_cost: // jump here at the beginning if the node has no parent (it is the first node)
 

	
 
			/* All other tile costs will be calculated here. */
 
			segment_cost += Yapf().OneTileCost(cur.tile, cur.td);
 

	
 
			/* If we skipped some tunnel/bridge/station tiles, add their base cost */
 
			segment_cost += YAPF_TILE_LENGTH * tf->m_tiles_skipped;
 

	
 
			/* Slope cost. */
 
			segment_cost += Yapf().SlopeCost(cur.tile, cur.td);
 

	
 
			/* Reserved tiles. */
 
			segment_cost += Yapf().ReservationCost(n, cur.tile, cur.td, tf->m_tiles_skipped);
 

	
 
			/* Signal cost (routine can modify segment data). */
 
			segment_cost += Yapf().SignalCost(n, cur.tile, cur.td);
 
			end_segment_reason = segment.m_end_segment_reason;
 

	
 
			/* Tests for 'potential target' reasons to close the segment. */
 
			if (cur.tile == prev.tile) {
 
				/* Penalty for reversing in a depot. */
 
				assert(IsRailDepot(cur.tile));
 
				segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty;
 
				/* We will end in this pass (depot is possible target) */
 
				end_segment_reason |= ESRB_DEPOT;
 

	
0 comments (0 inline, 0 general)