TrainRouteMetric::TrainRouteMetric(const TrackChain &tc, TrackChain::Direction dir)
{
+ /* Initialize goals for tracks in the target chain. We travel outwards from
+ the target in the search phase so the iters appear to point the wrong way. */
+ TrackChain::Direction reverse_dir = (dir==TrackChain::DOWN ? TrackChain::UP : TrackChain::DOWN);
const TrackChain::TrackSet &ctracks = tc.get_tracks();
for(TrackChain::TrackSet::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i)
{
queue.push_back(i->track);
}
+ /* Use Dijkstra's algorithm to find the shortest distance from the goal to
+ every reachable track in the layout. Entry points here become exit points
+ when looking up distances to the goal. */
while(!queue.empty())
{
TrackIter track = queue.front();
i->base_distance = metric.get_distance_from(*i->track.track(), i->track.entry());
}
+float TrainRouteMetric::get_distance_from(const Track &track) const
+{
+ map<Key, Data>::const_iterator i = tracks.lower_bound(Key(&track, 0));
+ map<Key, Data>::const_iterator j = tracks.upper_bound(Key(&track, 255));
+
+ float result = -1;
+ for(; i!=j; ++i)
+ {
+ float d = i->second.distance+i->second.goal->base_distance;
+ if(result<0 || d<result)
+ result = d;
+ }
+
+ return result;
+}
+
float TrainRouteMetric::get_distance_from(const Track &track, unsigned exit) const
{
map<Key, Data>::const_iterator i = tracks.find(Key(&track, exit));