summaryrefslogtreecommitdiff
path: root/src/yapf
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2008-08-02 22:51:07 +0000
committerrubidium <rubidium@openttd.org>2008-08-02 22:51:07 +0000
commit27cfb68d939d527dbe6c8c342539ed0cb355e95e (patch)
treefb6425f4783058dfae1fd7d48f11b66496f4ac6f /src/yapf
parent74b770a96a834cea6b3a4b32d30a301863160b7c (diff)
downloadopenttd-27cfb68d939d527dbe6c8c342539ed0cb355e95e.tar.xz
(svn r13941) -Codechange [YAPP]: Added YAPP-related penalties to YAPF. (michi_cc)
Diffstat (limited to 'src/yapf')
-rw-r--r--src/yapf/yapf_costrail.hpp107
1 files changed, 66 insertions, 41 deletions
diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp
index 509cba5d7..7ff99bb60 100644
--- a/src/yapf/yapf_costrail.hpp
+++ b/src/yapf/yapf_costrail.hpp
@@ -5,6 +5,7 @@
#ifndef YAPF_COSTRAIL_HPP
#define YAPF_COSTRAIL_HPP
+#include "../pbs.h"
template <class Types>
class CYapfCostRailT
@@ -128,6 +129,19 @@ public:
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;
@@ -139,50 +153,58 @@ public:
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;
-
- // look-ahead signal penalty
- if (look_ahead_cost > 0) {
- // add the look ahead penalty only if it is positive
- cost += look_ahead_cost;
- }
+ } 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;
- // 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;
- };
+ // 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;
+ };
+ }
}
+
+ 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;
}
- n.m_num_signals_passed++;
- n.m_segment->m_last_signal_tile = tile;
- n.m_segment->m_last_signal_td = trackdir;
}
}
return cost;
@@ -327,6 +349,9 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
/* 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;