OpenTTD Source  20240917-master-g9ab0a47812
yapf_common.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #ifndef YAPF_COMMON_HPP
11 #define YAPF_COMMON_HPP
12 
14 template <class Types>
16 {
17 public:
18  typedef typename Types::Tpf Tpf;
19  typedef typename Types::NodeList::Titem Node;
20  typedef typename Node::Key Key;
21 
22 protected:
25 
27  inline Tpf &Yapf()
28  {
29  return *static_cast<Tpf *>(this);
30  }
31 
32 public:
34  void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
35  {
36  m_orgTile = tile;
37  m_orgTrackdirs = trackdirs;
38  }
39 
42  {
43  bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
44  for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
45  Trackdir td = (Trackdir)FindFirstBit(tdb);
46  Node &n1 = Yapf().CreateNewNode();
47  n1.Set(nullptr, m_orgTile, td, is_choice);
48  Yapf().AddStartupNode(n1);
49  }
50  }
51 };
52 
54 template <class Types>
56 {
57 public:
58  typedef typename Types::Tpf Tpf;
59  typedef typename Types::NodeList::Titem Node;
60  typedef typename Node::Key Key;
61 
62 protected:
69 
71  inline Tpf &Yapf()
72  {
73  return *static_cast<Tpf *>(this);
74  }
75 
76 public:
78  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)
79  {
80  m_orgTile = tile;
81  m_orgTd = td;
82  m_revTile = tiler;
83  m_revTd = tdr;
84  m_reverse_penalty = reverse_penalty;
85  m_treat_first_red_two_way_signal_as_eol = treat_first_red_two_way_signal_as_eol;
86  }
87 
90  {
92  Node &n1 = Yapf().CreateNewNode();
93  n1.Set(nullptr, m_orgTile, m_orgTd, false);
94  Yapf().AddStartupNode(n1);
95  }
97  Node &n2 = Yapf().CreateNewNode();
98  n2.Set(nullptr, m_revTile, m_revTd, false);
99  n2.m_cost = m_reverse_penalty;
100  Yapf().AddStartupNode(n2);
101  }
102  }
103 
106  {
107  return Yapf().PfGetSettings().rail_firstred_twoway_eol && m_treat_first_red_two_way_signal_as_eol;
108  }
109 };
110 
112 template <class Types>
114 {
115 public:
116  typedef typename Types::Tpf Tpf;
117  typedef typename Types::NodeList::Titem Node;
118  typedef typename Node::Key Key;
119 
120 protected:
123 
124 public:
126  void SetDestination(TileIndex tile, TrackdirBits trackdirs)
127  {
128  m_destTile = tile;
129  m_destTrackdirs = trackdirs;
130  }
131 
132 protected:
135  {
136  return *static_cast<Tpf *>(this);
137  }
138 
139 public:
141  inline bool PfDetectDestination(Node &n)
142  {
143  return (n.m_key.m_tile == m_destTile) && HasTrackdir(m_destTrackdirs, n.GetTrackdir());
144  }
145 
150  inline bool PfCalcEstimate(Node &n)
151  {
152  static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
153  static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
154  if (PfDetectDestination(n)) {
155  n.m_estimate = n.m_cost;
156  return true;
157  }
158 
159  TileIndex tile = n.GetTile();
160  DiagDirection exitdir = TrackdirToExitdir(n.GetTrackdir());
161  int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
162  int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
163  int x2 = 2 * TileX(m_destTile);
164  int y2 = 2 * TileY(m_destTile);
165  int dx = abs(x1 - x2);
166  int dy = abs(y1 - y2);
167  int dmin = std::min(dx, dy);
168  int dxy = abs(dx - dy);
169  int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
170  n.m_estimate = n.m_cost + d;
171  assert(n.m_estimate >= n.m_parent->m_estimate);
172  return true;
173  }
174 };
175 
182 template <class Ttypes>
183 class CYapfT
184  : public Ttypes::PfBase
185  , public Ttypes::PfCost
186  , public Ttypes::PfCache
187  , public Ttypes::PfOrigin
188  , public Ttypes::PfDestination
189  , public Ttypes::PfFollow
190 {
191 };
192 
193 
194 
195 #endif /* YAPF_COMMON_HPP */
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
CYapfDestinationTileT::Yapf
Tpf & Yapf()
to access inherited path finder
Definition: yapf_common.hpp:134
CYapfOriginTileT::PfSetStartupNodes
void PfSetStartupNodes()
Called when YAPF needs to place origin nodes into open list.
Definition: yapf_common.hpp:41
CYapfOriginTileTwoWayT::m_revTile
TileIndex m_revTile
second (reversed) origin tile
Definition: yapf_common.hpp:65
TrackdirToExitdir
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition: track_func.h:439
CYapfDestinationTileT::PfCalcEstimate
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
Definition: yapf_common.hpp:150
CYapfOriginTileT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Definition: yapf_common.hpp:18
CYapfDestinationTileT::PfDetectDestination
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Definition: yapf_common.hpp:141
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
CYapfOriginTileTwoWayT::m_revTd
Trackdir m_revTd
second (reversed) origin trackdir
Definition: yapf_common.hpp:66
CYapfOriginTileTwoWayT::TreatFirstRedTwoWaySignalAsEOL
bool TreatFirstRedTwoWaySignalAsEOL()
return true if first two-way signal should be treated as dead end
Definition: yapf_common.hpp:105
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
CYapfOriginTileTwoWayT::m_orgTd
Trackdir m_orgTd
first origin trackdir
Definition: yapf_common.hpp:64
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
CYapfT
YAPF template that uses Ttypes template argument to determine all YAPF components (base classes) from...
Definition: yapf_common.hpp:183
KillFirstBit
constexpr T KillFirstBit(T value)
Clear the first bit in an integer.
Definition: bitmath_func.hpp:250
CYapfOriginTileT
YAPF origin provider base class - used when origin is one tile / multiple trackdirs.
Definition: yapf_common.hpp:15
CYapfOriginTileTwoWayT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Definition: yapf_common.hpp:58
CYapfOriginTileTwoWayT
YAPF origin provider base class - used when there are two tile/trackdir origins.
Definition: yapf_common.hpp:55
CYapfOriginTileTwoWayT::m_orgTile
TileIndex m_orgTile
first origin tile
Definition: yapf_common.hpp:63
CYapfDestinationTileT
YAPF destination provider base class - used when destination is single tile / multiple trackdirs.
Definition: yapf_common.hpp:113
YAPF_TILE_LENGTH
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
Definition: pathfinder_type.h:16
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:99
CYapfOriginTileT::Key
Node::Key Key
key to hash tables
Definition: yapf_common.hpp:20
CYapfOriginTileTwoWayT::m_treat_first_red_two_way_signal_as_eol
bool m_treat_first_red_two_way_signal_as_eol
in some cases (leaving station) we need to handle first two-way signal differently
Definition: yapf_common.hpp:68
CYapfDestinationTileT::SetDestination
void SetDestination(TileIndex tile, TrackdirBits trackdirs)
set the destination tile / more trackdirs
Definition: yapf_common.hpp:126
CYapfOriginTileTwoWayT::PfSetStartupNodes
void PfSetStartupNodes()
Called when YAPF needs to place origin nodes into open list.
Definition: yapf_common.hpp:89
CYapfDestinationTileT::Node
Types::NodeList::Titem Node
this will be our node type
Definition: yapf_common.hpp:117
CYapfDestinationTileT::m_destTrackdirs
TrackdirBits m_destTrackdirs
destination trackdir mask
Definition: yapf_common.hpp:122
CYapfOriginTileTwoWayT::Yapf
Tpf & Yapf()
to access inherited path finder
Definition: yapf_common.hpp:71
CYapfOriginTileT::m_orgTrackdirs
TrackdirBits m_orgTrackdirs
origin trackdir mask
Definition: yapf_common.hpp:24
CYapfDestinationTileT::m_destTile
TileIndex m_destTile
destination tile
Definition: yapf_common.hpp:121
CYapfOriginTileT::SetOrigin
void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
Set origin tile / trackdir mask.
Definition: yapf_common.hpp:34
CYapfDestinationTileT::Key
Node::Key Key
key to hash tables
Definition: yapf_common.hpp:118
CYapfOriginTileT::Yapf
Tpf & Yapf()
to access inherited path finder
Definition: yapf_common.hpp:27
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:67
abs
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:23
CYapfOriginTileTwoWayT::Key
Node::Key Key
key to hash tables
Definition: yapf_common.hpp:60
CYapfOriginTileTwoWayT::m_reverse_penalty
int m_reverse_penalty
penalty to be added for using the reversed origin
Definition: yapf_common.hpp:67
CYapfOriginTileT::m_orgTile
TileIndex m_orgTile
origin tile
Definition: yapf_common.hpp:23
YAPF_TILE_CORNER_LENGTH
static const int YAPF_TILE_CORNER_LENGTH
Length (penalty) of a corner with YAPF.
Definition: pathfinder_type.h:19
CYapfOriginTileTwoWayT::SetOrigin
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)
set origin (tiles, trackdirs, etc.)
Definition: yapf_common.hpp:78
TrackdirBits
TrackdirBits
Allow incrementing of Trackdir variables.
Definition: track_type.h:98
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
HasTrackdir
bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir)
Checks whether a TrackdirBits has a given Trackdir.
Definition: track_func.h:340
CYapfOriginTileT::Node
Types::NodeList::Titem Node
this will be our node type
Definition: yapf_common.hpp:19
CYapfDestinationTileT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Definition: yapf_common.hpp:116
INVALID_TRACKDIR
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition: track_type.h:86
CYapfOriginTileTwoWayT::Node
Types::NodeList::Titem Node
this will be our node type
Definition: yapf_common.hpp:59
FindFirstBit
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
Definition: bitmath_func.hpp:213