--- a/yapf/yapf_costrail.hpp Mon Jan 01 18:27:08 2007 +0000
+++ b/yapf/yapf_costrail.hpp Mon Jan 01 19:44:02 2007 +0000
@@ -195,38 +195,57 @@
Trackdir trackdir = n.m_key.m_td;
TileType tile_type = GetTileType(tile);
+ DEBUG(yapf, 3, "PfCalcCost(Node:tile=%04X td=%s; Parent:tile=%04X td=%s)", tile, GetTrackdirName(trackdir), prev_tile, GetTrackdirName(prev_trackdir));
+
RailType rail_type = GetTileRailType(tile, trackdir);
// detect exit from bridge wormhole
if (IsBridgeTile(tile) && TrackdirToExitdir(ReverseTrackdir(trackdir)) == GetBridgeRampDirection(tile)) {
// we are jumping over bridge (possible now with custom bridge heads) we must add the cost of skipped tiles
- segment_cost += (DistanceManhattan(prev_tile, tile) - 1) * YAPF_TILE_LENGTH;
+ int skipped_tiles = DistanceManhattan(prev_tile, tile) - 1;
+ if (skipped_tiles > 0) {
+ segment_cost += skipped_tiles * YAPF_TILE_LENGTH;
+ DEBUG(yapf, 6, " Cost: skipped=%d", skipped_tiles * YAPF_TILE_LENGTH);
+ intermediate_trackdir = DiagdirToDiagTrackdir(ReverseDiagDir(GetBridgeRampDirection(tile)));
+ }
}
bool target_seen = Yapf().PfDetectDestination(tile, trackdir);
while (true) {
- segment_cost += Yapf().OneTileCost(tile, trackdir);
- segment_cost += Yapf().CurveCost(prev_trackdir, trackdir);
- segment_cost += Yapf().SlopeCost(tile, trackdir);
- segment_cost += Yapf().SignalCost(n, tile, trackdir);
+ int tile_cost = Yapf().OneTileCost(tile, trackdir);
+ int curve_cost;
+ if (intermediate_trackdir == INVALID_TRACKDIR) {
+ curve_cost = Yapf().CurveCost(prev_trackdir, trackdir);
+ } else {
+ curve_cost = Yapf().CurveCost(prev_trackdir, intermediate_trackdir) + Yapf().CurveCost(intermediate_trackdir, trackdir);
+ intermediate_trackdir = INVALID_TRACKDIR;
+ }
+ int slope_cost = Yapf().SlopeCost(tile, trackdir);
+ int signal_cost = Yapf().SignalCost(n, tile, trackdir);
+ DEBUG(yapf, 6, " Cost: tile=%d, curve=%d, slope=%d, signal=%d", tile_cost, curve_cost, slope_cost, signal_cost);
+ segment_cost += tile_cost + curve_cost + slope_cost + signal_cost;
if (n.m_segment->flags_u.flags_s.m_end_of_line) {
+ DEBUG(yapf, 4, " end: EOL (signal)");
break;
}
// finish if we have reached the destination
if (target_seen) {
+ DEBUG(yapf, 4, " end: target_seen");
break;
}
// finish on first station tile - segment should end here to avoid target skipping
// when cached segments are used
if (tile_type == MP_STATION && prev_tile_type != MP_STATION) {
+ DEBUG(yapf, 4, " end: first station tile");
break;
}
// finish also on waypoint - same workaround as for first station tile
if (tile_type == MP_RAILWAY && IsRailWaypoint(tile)) {
+ DEBUG(yapf, 4, " end: waypoint");
break;
}
@@ -235,11 +254,15 @@
if (!F.Follow(tile, trackdir)) {
// we can't continue?
// n.m_segment->flags_u.flags_s.m_end_of_line = true;
+ DEBUG(yapf, 4, " end: can't foolow (dead end?)");
break;
}
+ if (F.m_is_bridge && F.m_tiles_skipped > 0) intermediate_trackdir = F.m_intermediate_trackdir;
+ DEBUG(yapf, 4, " next: tile=%04X td=%s", F.m_new_tile, GetTrackdirBitsName(F.m_new_td_bits).Data());
// if there are more trackdirs available & reachable, we are at the end of segment
if (KillFirstBit2x64(F.m_new_td_bits) != 0) {
+ DEBUG(yapf, 4, " end: choice");
break;
}
@@ -248,18 +271,23 @@
{
// end segment if train is about to enter simple loop with no junctions
// so next time it should stop on the next if
- if (segment_cost > s_max_segment_cost && IsTileType(F.m_new_tile, MP_RAILWAY))
+ if (segment_cost > s_max_segment_cost && IsTileType(F.m_new_tile, MP_RAILWAY)) {
+ DEBUG(yapf, 4, " end: loop fuse");
break;
+ }
// stop if train is on simple loop with no junctions
- if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td)
+ if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) {
+ DEBUG(yapf, 4, " end: loop detected");
return false;
+ }
}
- // if tail type changes, finish segment (cached segment can't contain more rail types)
+ // if rail type changes, finish segment (cached segment can't contain more rail types)
{
RailType new_rail_type = GetTileRailType(F.m_new_tile, (Trackdir)FindFirstBit2x64(F.m_new_td_bits));
if (new_rail_type != rail_type) {
+ DEBUG(yapf, 4, " end: rail type changes");
break;
}
rail_type = new_rail_type;
@@ -278,12 +306,15 @@
// reversing in depot penalty
if (tile == prev_tile) {
- segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty;
+ int reverse_in_depot_cost = Yapf().PfGetSettings().rail_depot_reverse_penalty;
+ segment_cost += reverse_in_depot_cost;
+ DEBUG(yapf, 4, " end: reversing in depot (cost=%d)", reverse_in_depot_cost);
break;
}
// if we skipped some tunnel tiles, add their cost
segment_cost += YAPF_TILE_LENGTH * F.m_tiles_skipped;
+ DEBUG(yapf, 6, " Cost: wormhole=%d", YAPF_TILE_LENGTH * F.m_tiles_skipped);
// add penalty for skipped station tiles
if (F.m_is_station)
@@ -291,10 +322,14 @@
if (target_seen) {
// it is our destination station
uint platform_length = F.m_tiles_skipped + 1;
- segment_cost += PlatformLengthPenalty(platform_length);
+ int platform_length_cost = PlatformLengthPenalty(platform_length);
+ segment_cost += platform_length_cost;
+ DEBUG(yapf, 6, " Cost: platform=%d", platform_length_cost);
} else {
// station is not our destination station, apply penalty for skipped platform tiles
- segment_cost += Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped;
+ int station_cost = Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped;
+ segment_cost += station_cost;
+ DEBUG(yapf, 6, " Cost: station=%d", station_cost);
}
}
@@ -308,6 +343,7 @@
// finish if we already exceeded the maximum cost
if (m_max_cost > 0 && (parent_cost + first_tile_cost + segment_cost) > m_max_cost) {
+ DEBUG(yapf, 4, " abort: maximum cost reached");
return false;
}
@@ -315,10 +351,12 @@
// we just have done first tile
first_tile_cost = segment_cost;
segment_cost = 0;
+ DEBUG(yapf, 5, " TotalCost: first_tile=%d", first_tile_cost);
// look if we can reuse existing (cached) segment cost
if (n.m_segment->m_cost >= 0) {
// reuse the cached segment cost
+ DEBUG(yapf, 4, " end: reusing the cached segment cost");
break;
}
}
@@ -331,15 +369,18 @@
// we have just finished first tile
first_tile_cost = segment_cost;
segment_cost = 0;
+ DEBUG(yapf, 5, " TotalCost: first_tile=%d", first_tile_cost);
}
// do we have cached segment cost?
if (n.m_segment->m_cost >= 0) {
// reuse the cached segment cost
segment_cost = n.m_segment->m_cost;
+ DEBUG(yapf, 5, " TotalCost: cached_segment=%d", segment_cost);
} else {
// save segment cost
n.m_segment->m_cost = segment_cost;
+ DEBUG(yapf, 5, " TotalCost: segment=%d", segment_cost);
// save end of segment back to the node
n.SetLastTileTrackdir(tile, trackdir);
@@ -358,10 +399,12 @@
}
}
}
+ DEBUG(yapf, 5, " TotalCost: extra=%d", extra_cost);
// total node cost
n.m_cost = parent_cost + first_tile_cost + segment_cost + extra_cost;
-
+ DEBUG(yapf, 3, " leaving: last_tile=%04X, last_td=%s, cost=%d", n.m_segment->m_last_tile, GetTrackdirName(n.m_segment->m_last_td), n.m_cost);
+ DEBUG(yapf, 3, " returning %s", n.m_segment->flags_u.flags_s.m_end_of_line ? "false" : "true");
return !n.m_segment->flags_u.flags_s.m_end_of_line;
}