Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef YAPF_COMMON_HPP
00013 #define YAPF_COMMON_HPP
00014
00016 template <class Types>
00017 class CYapfOriginTileT
00018 {
00019 public:
00020 typedef typename Types::Tpf Tpf;
00021 typedef typename Types::NodeList::Titem Node;
00022 typedef typename Node::Key Key;
00023
00024 protected:
00025 TileIndex m_orgTile;
00026 TrackdirBits m_orgTrackdirs;
00027
00029 inline Tpf& Yapf()
00030 {
00031 return *static_cast<Tpf*>(this);
00032 }
00033
00034 public:
00036 void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
00037 {
00038 m_orgTile = tile;
00039 m_orgTrackdirs = trackdirs;
00040 }
00041
00043 void PfSetStartupNodes()
00044 {
00045 bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
00046 for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
00047 Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
00048 Node& n1 = Yapf().CreateNewNode();
00049 n1.Set(NULL, m_orgTile, td, is_choice);
00050 Yapf().AddStartupNode(n1);
00051 }
00052 }
00053 };
00054
00056 template <class Types>
00057 class CYapfOriginTileTwoWayT
00058 {
00059 public:
00060 typedef typename Types::Tpf Tpf;
00061 typedef typename Types::NodeList::Titem Node;
00062 typedef typename Node::Key Key;
00063
00064 protected:
00065 TileIndex m_orgTile;
00066 Trackdir m_orgTd;
00067 TileIndex m_revTile;
00068 Trackdir m_revTd;
00069 int m_reverse_penalty;
00070 bool m_treat_first_red_two_way_signal_as_eol;
00071
00073 inline Tpf& Yapf()
00074 {
00075 return *static_cast<Tpf*>(this);
00076 }
00077
00078 public:
00080 void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0, bool treat_first_red_two_way_signal_as_eol = true)
00081 {
00082 m_orgTile = tile;
00083 m_orgTd = td;
00084 m_revTile = tiler;
00085 m_revTd = tdr;
00086 m_reverse_penalty = reverse_penalty;
00087 m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
00088 }
00089
00091 void PfSetStartupNodes()
00092 {
00093 if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) {
00094 Node& n1 = Yapf().CreateNewNode();
00095 n1.Set(NULL, m_orgTile, m_orgTd, false);
00096 Yapf().AddStartupNode(n1);
00097 }
00098 if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) {
00099 Node& n2 = Yapf().CreateNewNode();
00100 n2.Set(NULL, m_revTile, m_revTd, false);
00101 n2.m_cost = m_reverse_penalty;
00102 Yapf().AddStartupNode(n2);
00103 }
00104 }
00105
00107 inline bool TreatFirstRedTwoWaySignalAsEOL()
00108 {
00109 return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
00110 }
00111 };
00112
00114 template <class Types>
00115 class CYapfDestinationTileT
00116 {
00117 public:
00118 typedef typename Types::Tpf Tpf;
00119 typedef typename Types::NodeList::Titem Node;
00120 typedef typename Node::Key Key;
00121
00122 protected:
00123 TileIndex m_destTile;
00124 TrackdirBits m_destTrackdirs;
00125
00126 public:
00128 void SetDestination(TileIndex tile, TrackdirBits trackdirs)
00129 {
00130 m_destTile = tile;
00131 m_destTrackdirs = trackdirs;
00132 }
00133
00134 protected:
00136 Tpf& Yapf()
00137 {
00138 return *static_cast<Tpf*>(this);
00139 }
00140
00141 public:
00143 inline bool PfDetectDestination(Node& n)
00144 {
00145 bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
00146 return bDest;
00147 }
00148
00153 inline bool PfCalcEstimate(Node& n)
00154 {
00155 static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00156 static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00157 if (PfDetectDestination(n)) {
00158 n.m_estimate = n.m_cost;
00159 return true;
00160 }
00161
00162 TileIndex tile = n.GetTile();
00163 DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
00164 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00165 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00166 int x2 = 2 * TileX(m_destTile);
00167 int y2 = 2 * TileY(m_destTile);
00168 int dx = abs(x1 - x2);
00169 int dy = abs(y1 - y2);
00170 int dmin = min(dx, dy);
00171 int dxy = abs(dx - dy);
00172 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00173 n.m_estimate = n.m_cost + d;
00174 assert(n.m_estimate >= n.m_parent->m_estimate);
00175 return true;
00176 }
00177 };
00178
00185 template <class Ttypes>
00186 class CYapfT
00187 : public Ttypes::PfBase
00188 , public Ttypes::PfCost
00189 , public Ttypes::PfCache
00190 , public Ttypes::PfOrigin
00191 , public Ttypes::PfDestination
00192 , public Ttypes::PfFollow
00193 {
00194 };
00195
00196
00197
00198 #endif