27 #define LOG_PF LOG_STREAM(info, log_engine)
28 #define DBG_PF LOG_STREAM(debug, log_engine)
29 #define ERR_PF LOG_STREAM(err, log_engine)
42 double xdiff = (src.
x - dst.
x) * 0.75;
44 double ydiff = (src.
y - dst.
y) + ((src.
x & 1) - (dst.
x & 1)) * 0.5;
53 return distance_between(src, dst) + (xdiff*xdiff + ydiff*ydiff) / 900000000.0;
61 const unsigned bad_search_counter = 0;
63 static unsigned search_counter = bad_search_counter;
81 , in(bad_search_counter)
85 g(s), h(heuristic(c, dst)), t(g + h), curr(c), prev(p), in(search_counter + i)
87 if (teleports && !teleports->empty()) {
89 double new_srch = 1.0;
91 teleports->get_sources(sources);
93 std::set<map_location>::const_iterator it = sources.begin();
94 for(; it != sources.end(); ++it) {
95 const double tmp_srch = heuristic(c, *it);
96 if (tmp_srch < new_srch) { new_srch = tmp_srch; }
100 double new_dsth = 1.0;
101 std::set<map_location> targets;
102 teleports->get_targets(targets);
104 for(it = targets.begin(); it != targets.end(); ++it) {
105 const double tmp_dsth = heuristic(*it, dst);
106 if (tmp_dsth < new_dsth) { new_dsth = tmp_dsth; }
109 double new_h = new_srch + new_dsth + 1.0;
126 comp(
const std::vector<node>&
n) : nodes_(n) { }
127 bool operator()(
int a,
int b) {
128 return nodes_[
b] < nodes_[
a];
136 indexer(
size_t w) : w_(w) { }
138 return loc.
y * w_ + loc.
x;
149 assert(src.
valid(width, height, border));
150 assert(dst.
valid(width, height, border));
151 assert(calc !=
nullptr);
152 assert(stop_at <= calc->getNoPathValue());
155 DBG_PF <<
"A* search: " << src <<
" -> " << dst <<
'\n';
157 if (calc->
cost(dst, 0) >= stop_at) {
158 LOG_PF <<
"aborted A* search because Start or Dest is invalid\n";
166 if (search_counter - bad_search_counter <= 1u)
169 static std::vector<node>
nodes;
170 nodes.resize(width * height);
172 indexer
index(width);
173 comp node_comp(nodes);
175 nodes[
index(dst)].g = stop_at + 1;
179 pq.push_back(
index(src));
181 while (!pq.empty()) {
182 node&
n = nodes[pq.front()];
184 n.in = search_counter;
186 std::pop_heap(pq.begin(), pq.end(), node_comp);
189 if (n.t >= nodes[index(dst)].g)
break;
191 std::vector<map_location> locs(6);
193 if (teleports && !teleports->
empty()) {
195 std::set<map_location> allowed_teleports;
197 locs.insert(locs.end(), allowed_teleports.begin(), allowed_teleports.end());
205 if (!locs[i].
valid(width, height, border))
continue;
206 if (locs[i] == n.curr)
continue;
209 double thresh = (next.in - search_counter <= 1u) ? next.g : stop_at + 1;
211 if (n.g + 1 >= thresh)
continue;
212 double cost = n.g + calc->
cost(locs[i], n.g);
213 if (cost >= thresh)
continue;
215 bool in_list = next.in == search_counter + 1;
217 next = node(cost, locs[i], n.curr, dst,
true, teleports);
220 std::push_heap(pq.begin(),
std::find(pq.begin(), pq.end(),
static_cast<int>(
index(locs[i]))) + 1, node_comp);
222 pq.push_back(
index(locs[i]));
223 std::push_heap(pq.begin(), pq.end(), node_comp);
229 if (nodes[
index(dst)].g <= stop_at) {
230 DBG_PF <<
"found solution; calculating it...\n";
233 route.
steps.push_back(curr.curr);
235 route.
steps.push_back(src);
236 std::reverse(route.
steps.begin(), route.
steps.end());
238 LOG_PF <<
"aborted a* search " <<
"\n";
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator *calc, const size_t width, const size_t height, const teleport_map *teleports, bool border)
const std::vector< node > & nodes
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
static double getNoPathValue()
GLdouble GLdouble GLdouble b
std::vector< map_location > steps
Structure which holds a single route between one location and another.
size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
GLubyte GLubyte GLubyte GLubyte w
GLboolean GLboolean GLboolean GLboolean a
const std::vector< node > & nodes_
static const map_location & null_location()
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
int move_cost
Movement cost for reaching the end of the route.
Encapsulates the map of the game.
static bool operator<(const placing_info &a, const placing_info &b)
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
static lg::log_domain log_engine("engine")
GLint GLint GLsizei GLsizei GLsizei GLint border
virtual double cost(const map_location &loc, const double so_far) const =0
bool find(E event, F functor)
Tests whether an event handler is available.
Standard logging facilities (interface).
GLint GLint GLint GLint GLint GLint GLsizei width
unsigned in
If equal to search_counter, the node is off the list.
This module contains various pathfinding functions and utilities.
void get_adjacents(std::set< map_location > &adjacents, map_location loc) const
const std::string valid
Little parts of regex templates used to parse Wml annoations.