mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-21 16:24:38 +00:00
Reduced memory consumption of Dijkstra's solution...
...from quadratic to linear with respect to movement points.
This commit is contained in:
parent
89842480b5
commit
2632d77ea6
@ -19,6 +19,7 @@
|
||||
|
||||
#include "ai/testing.hpp"
|
||||
#include "attack_prediction.hpp"
|
||||
#include "foreach.hpp"
|
||||
#include "game_display.hpp"
|
||||
#include "game_end_exceptions.hpp"
|
||||
#include "game_events.hpp"
|
||||
@ -2102,9 +2103,8 @@ namespace {
|
||||
}
|
||||
|
||||
paths p(map,units,loc,teams,true,false,teams[team],0,false,true);
|
||||
for(paths::routes_map::const_iterator i = p.routes.begin();
|
||||
i != p.routes.end(); ++i) {
|
||||
clear_shroud_loc(map,teams[team],i->first,&cleared_locations);
|
||||
foreach (const paths::step &dest, p.destinations) {
|
||||
clear_shroud_loc(map, teams[team], dest.curr, &cleared_locations);
|
||||
}
|
||||
|
||||
// clear_shroud_loc is supposed not introduce repetition in cleared_locations
|
||||
|
@ -336,23 +336,22 @@ bool ai::multistep_move_possible(const location& from,
|
||||
|
||||
LOG_AI << "found leader moves..\n";
|
||||
|
||||
int move_left = 0;
|
||||
|
||||
// See if the unit can make it to 'via', and if it can,
|
||||
// how much movement it will have left when it gets there.
|
||||
const paths::routes_map::const_iterator itor = moves->second.routes.find(via);
|
||||
if(itor != moves->second.routes.end()) {
|
||||
move_left = itor->second.move_left;
|
||||
LOG_AI << "can make it to keep with " << move_left << " movement left\n";
|
||||
paths::dest_vect::const_iterator itor =
|
||||
moves->second.destinations.find(via);
|
||||
if (itor != moves->second.destinations.end())
|
||||
{
|
||||
LOG_AI << "Can make it to keep with " << itor->move_left << " movement left.\n";
|
||||
unit temp_unit(i->second);
|
||||
temp_unit.set_movement(move_left);
|
||||
temp_unit.set_movement(itor->move_left);
|
||||
const temporary_unit_placer unit_placer(units_,via,temp_unit);
|
||||
const paths unit_paths(map_,units_,via,teams_,false,false,current_team());
|
||||
|
||||
LOG_AI << "found " << unit_paths.routes.size() << " moves for temp leader\n";
|
||||
LOG_AI << "Found " << unit_paths.destinations.size() << " moves for temp leader.\n";
|
||||
|
||||
// See if this leader could make it back to the keep.
|
||||
if(unit_paths.routes.count(to) != 0) {
|
||||
if (unit_paths.destinations.contains(to)) {
|
||||
LOG_AI << "can make it back to the keep\n";
|
||||
return true;
|
||||
}
|
||||
@ -590,8 +589,6 @@ void ai::do_move()
|
||||
|
||||
raise_user_interact();
|
||||
|
||||
typedef paths::route route;
|
||||
|
||||
typedef std::map<location,paths> moves_map;
|
||||
moves_map possible_moves, enemy_possible_moves;
|
||||
|
||||
@ -1584,12 +1581,12 @@ void ai::move_leader_to_goals( const move_map& enemy_dstsrc)
|
||||
possible_moves.insert(std::pair<map_location,paths>(leader->first,leader_paths));
|
||||
|
||||
map_location loc;
|
||||
for(std::vector<map_location>::const_iterator itor = route.steps.begin();
|
||||
itor != route.steps.end(); ++itor) {
|
||||
|
||||
if(leader_paths.routes.count(*itor) == 1 &&
|
||||
power_projection(*itor,enemy_dstsrc) < double(leader->second.hitpoints()/2)) {
|
||||
loc = *itor;
|
||||
foreach (const map_location &l, route.steps)
|
||||
{
|
||||
if (leader_paths.destinations.contains(l) &&
|
||||
power_projection(l, enemy_dstsrc) < double(leader->second.hitpoints() / 2))
|
||||
{
|
||||
loc = l;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1629,13 +1626,14 @@ void ai::move_leader_after_recruit(const move_map& /*srcdst*/,
|
||||
int current_distance = distance_between(i->first,leader->first);
|
||||
location current_loc;
|
||||
|
||||
for(paths::routes_map::const_iterator j = leader_paths.routes.begin();
|
||||
j != leader_paths.routes.end(); ++j) {
|
||||
|
||||
const int distance = distance_between(i->first,j->first);
|
||||
if(distance < current_distance && is_accessible(j->first,enemy_dstsrc) == false) {
|
||||
foreach (const paths::step &dest, leader_paths.destinations)
|
||||
{
|
||||
const int distance = distance_between(i->first, dest.curr);
|
||||
if (distance < current_distance &&
|
||||
!is_accessible(dest.curr, enemy_dstsrc))
|
||||
{
|
||||
current_distance = distance;
|
||||
current_loc = j->first;
|
||||
current_loc = dest.curr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1649,7 +1647,8 @@ void ai::move_leader_after_recruit(const move_map& /*srcdst*/,
|
||||
const paths p(map_, temp_units, current_loc, teams_, false,
|
||||
false, current_team());
|
||||
|
||||
if(p.routes.count(i->first)) {
|
||||
if (p.destinations.contains(i->first))
|
||||
{
|
||||
move_unit(leader->first,current_loc,possible_moves);
|
||||
// FIXME: suokko's r29531 included this line
|
||||
// leader->second.set_movement(0);
|
||||
@ -1692,10 +1691,10 @@ void ai::move_leader_after_recruit(const move_map& /*srcdst*/,
|
||||
for(size_t n = 0; n != 6; ++n) {
|
||||
// Vacate to the first location found that is on the board,
|
||||
// our leader can move to, and no enemies can reach.
|
||||
if(map_.on_board(adj[n]) &&
|
||||
leader_paths.routes.count(adj[n]) != 0 &&
|
||||
is_accessible(adj[n],enemy_dstsrc) == false) {
|
||||
|
||||
if (map_.on_board(adj[n]) &&
|
||||
leader_paths.destinations.contains(adj[n]) &&
|
||||
!is_accessible(adj[n], enemy_dstsrc))
|
||||
{
|
||||
if (move_unit(keep,adj[n],possible_moves)!=keep) {
|
||||
return;
|
||||
}
|
||||
@ -1738,7 +1737,7 @@ bool ai::leader_can_reach_keep()
|
||||
const paths leader_paths(map_,units_,leader->first,teams_,false,false,current_team());
|
||||
|
||||
|
||||
return leader_paths.routes.count(start_pos) > 0;
|
||||
return leader_paths.destinations.contains(start_pos);
|
||||
}
|
||||
|
||||
int ai::rate_terrain(const unit& u, const map_location& loc)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../global.hpp"
|
||||
|
||||
#include "ai.hpp"
|
||||
#include "foreach.hpp"
|
||||
#include "../gettext.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "../map.hpp"
|
||||
@ -876,11 +877,12 @@ const map_location& ai::suitable_keep(const map_location& leader_location, const
|
||||
map_location const* best_occupied_keep = &map_location::null_location;
|
||||
double cost_to_best_occupied_keep = 0.0;
|
||||
|
||||
for(std::map<location,paths::route>::const_iterator rt = leader_paths.routes.begin(); rt != leader_paths.routes.end(); ++rt) {
|
||||
const map_location& loc = rt->first;
|
||||
foreach (const paths::step &dest, leader_paths.destinations)
|
||||
{
|
||||
const map_location &loc = dest.curr;
|
||||
if (keeps().find(loc)!=keeps().end()){
|
||||
//@todo 1.7 move_left for 1-turn-moves is really "cost_to_get_there", it is just not renamed there yet. see r34430 for more detais.
|
||||
const int cost_to_loc = rt->second.move_left;
|
||||
const int cost_to_loc = dest.move_left;
|
||||
if (units_.count(loc) == 0) {
|
||||
if ((*best_free_keep==map_location::null_location)||(cost_to_loc<cost_to_best_free_keep)){
|
||||
best_free_keep = &loc;
|
||||
@ -923,8 +925,7 @@ void ai::move_leader_to_keep(const move_map& enemy_dstsrc)
|
||||
|
||||
// If the leader is not on keep, move him there.
|
||||
if(leader->first != keep) {
|
||||
const paths::routes_map::const_iterator itor = leader_paths.routes.find(keep);
|
||||
if(itor != leader_paths.routes.end() && units_.count(keep) == 0) {
|
||||
if (leader_paths.destinations.contains(keep) && units_.count(keep) == 0) {
|
||||
move_unit(leader->first,keep,possible_moves);
|
||||
} else {
|
||||
// Make a map of the possible locations the leader can move to,
|
||||
@ -934,12 +935,11 @@ void ai::move_leader_to_keep(const move_map& enemy_dstsrc)
|
||||
// The leader can't move to his keep, try to move to the closest location
|
||||
// to the keep where there are no enemies in range.
|
||||
const int current_distance = distance_between(leader->first,keep);
|
||||
for(paths::routes_map::const_iterator i = leader_paths.routes.begin();
|
||||
i != leader_paths.routes.end(); ++i) {
|
||||
|
||||
const int new_distance = distance_between(i->first,keep);
|
||||
foreach (const paths::step &dest, leader_paths.destinations)
|
||||
{
|
||||
const int new_distance = distance_between(dest.curr,keep);
|
||||
if(new_distance < current_distance) {
|
||||
moves_toward_keep.insert(std::pair<int,map_location>(new_distance,i->first));
|
||||
moves_toward_keep.insert(std::make_pair(new_distance, dest.curr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,31 +249,25 @@ map_location ai_readwrite_context::move_unit_partial(map_location from, map_loca
|
||||
|
||||
if(p_it != possible_moves.end()) {
|
||||
paths& p = p_it->second;
|
||||
std::map<map_location,paths::route>::iterator rt = p.routes.begin();
|
||||
for(; rt != p.routes.end(); ++rt) {
|
||||
if(rt->first == to) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
paths::dest_vect::const_iterator rt = p.destinations.find(to);
|
||||
if (rt != p.destinations.end())
|
||||
{
|
||||
u_it->second.set_movement(rt->move_left);
|
||||
|
||||
if(rt != p.routes.end()) {
|
||||
if (static_cast<size_t>(u_it->second.movement_left()) >= rt->second.steps.size()) {
|
||||
LOG_AI<<"Trying to move unit without enough move points left\n";
|
||||
}
|
||||
u_it->second.set_movement(rt->second.move_left);
|
||||
|
||||
steps = rt->second.steps;
|
||||
|
||||
while(steps.empty() == false && get_info().units.find(to) != get_info().units.end() && from != to){
|
||||
while (rt != p.destinations.end() &&
|
||||
get_info().units.find(to) != get_info().units.end() && from != to)
|
||||
{
|
||||
LOG_AI << "AI attempting illegal move. Attempting to move onto existing unit\n";
|
||||
LOG_AI << "\t" << get_info().units.find(to)->second.underlying_id() <<" already on " << to << "\n";
|
||||
LOG_AI <<"\tremoving "<<*(steps.end()-1)<<"\n";
|
||||
to = *(steps.end()-1);
|
||||
steps.pop_back();
|
||||
LOG_AI <<"\tremoving last step\n";
|
||||
to = rt->prev;
|
||||
rt = p.destinations.find(to);
|
||||
LOG_AI << "\tresetting to " << from << " -> " << to << '\n';
|
||||
}
|
||||
|
||||
if(steps.size()) { // First step is starting hex
|
||||
if (rt != p.destinations.end()) // First step is starting hex
|
||||
{
|
||||
steps = p.destinations.get_path(rt);
|
||||
unit_map::const_iterator utest=get_info().units.find(*(steps.begin()));
|
||||
if(utest != get_info().units.end() && current_team().is_enemy(utest->second.side())){
|
||||
ERR_AI << "AI tried to move onto existing enemy unit at" << *steps.begin() << '\n';
|
||||
@ -441,10 +435,10 @@ void ai_readonly_context::calculate_moves(const unit_map& units, std::map<map_lo
|
||||
}
|
||||
|
||||
for(std::map<map_location,paths>::iterator m = res.begin(); m != res.end(); ++m) {
|
||||
for(paths::routes_map::iterator rtit =
|
||||
m->second.routes.begin(); rtit != m->second.routes.end(); ++rtit) {
|
||||
foreach (const paths::step &dest, m->second.destinations)
|
||||
{
|
||||
const map_location& src = m->first;
|
||||
const map_location& dst = rtit->first;
|
||||
const map_location& dst = dest.curr;
|
||||
|
||||
if(remove_destinations != NULL && remove_destinations->count(dst) != 0) {
|
||||
continue;
|
||||
|
@ -1994,8 +1994,8 @@ map_location formula_ai::path_calculator(const map_location& src, const map_loca
|
||||
map_location destination = dst;
|
||||
|
||||
//check if destination is within unit's reach, if not, calculate where to move
|
||||
if( path->second.routes.count(dst) == 0) {
|
||||
|
||||
if (!path->second.destinations.contains(dst))
|
||||
{
|
||||
std::set<map_location> allowed_teleports = get_allowed_teleports(unit_it);
|
||||
//destination is too far, check where unit can go
|
||||
|
||||
@ -2120,7 +2120,7 @@ bool formula_ai::execute_variant(const variant& var, bool commandline)
|
||||
|
||||
std::map<map_location,paths>::iterator path = possible_moves_.find(attack->move_from());
|
||||
|
||||
if( path->second.routes.count(attack->src()) == 0) {
|
||||
if (!path->second.destinations.contains(attack->src())) {
|
||||
ERR_AI << "IMPOSSIBLE ATTACK ORDER\n";
|
||||
continue;
|
||||
}
|
||||
|
@ -741,11 +741,9 @@ void game_display::highlight_reach(const paths &paths_list)
|
||||
|
||||
void game_display::highlight_another_reach(const paths &paths_list)
|
||||
{
|
||||
paths::routes_map::const_iterator r;
|
||||
|
||||
// Fold endpoints of routes into reachability map.
|
||||
for (r = paths_list.routes.begin(); r != paths_list.routes.end(); ++r) {
|
||||
reach_map_[r->first]++;
|
||||
foreach (const paths::step &dest, paths_list.destinations) {
|
||||
reach_map_[dest.curr]++;
|
||||
}
|
||||
reach_map_changed_ = true;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update)
|
||||
if (update) {
|
||||
if (reachmap_invalid_) {
|
||||
reachmap_invalid_ = false;
|
||||
if (!current_paths_.routes.empty() && !show_partial_move_) {
|
||||
if (!current_paths_.destinations.empty() && !show_partial_move_) {
|
||||
unit_map::iterator u = find_unit(selected_hex_);
|
||||
if(selected_hex_.valid() && u != units_.end() ) {
|
||||
// reselect the unit without firing events (updates current_paths_)
|
||||
@ -155,7 +155,10 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update)
|
||||
&& !selected_unit->second.incapacitated() && !browse) {
|
||||
if (attack_from.valid()) {
|
||||
cursor::set(dragging_started_ ? cursor::ATTACK_DRAG : cursor::ATTACK);
|
||||
} else if (mouseover_unit==units_.end() && current_paths_.routes.count(new_hex)) {
|
||||
}
|
||||
else if (mouseover_unit==units_.end() &&
|
||||
current_paths_.destinations.contains(new_hex))
|
||||
{
|
||||
cursor::set(dragging_started_ ? cursor::MOVE_DRAG : cursor::MOVE);
|
||||
} else {
|
||||
// selecte unit can't attack or move there
|
||||
@ -189,9 +192,10 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update)
|
||||
if(dest == selected_hex_ || dest_un != units_.end()) {
|
||||
current_route_.steps.clear();
|
||||
gui().set_route(NULL);
|
||||
} else if(!current_paths_.routes.empty() && map_.on_board(selected_hex_) &&
|
||||
map_.on_board(new_hex)) {
|
||||
|
||||
}
|
||||
else if (!current_paths_.destinations.empty() &&
|
||||
map_.on_board(selected_hex_) && map_.on_board(new_hex))
|
||||
{
|
||||
if(selected_unit != units_.end() && !selected_unit->second.incapacitated()) {
|
||||
// the movement_reset is active only if it's not the unit's turn
|
||||
unit_movement_resetter move_reset(selected_unit->second,
|
||||
@ -205,7 +209,9 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update)
|
||||
|
||||
unit_map::iterator un = mouseover_unit;
|
||||
|
||||
if(un != units_.end() && current_paths_.routes.empty() && !gui().fogged(un->first)) {
|
||||
if (un != units_.end() && current_paths_.destinations.empty() &&
|
||||
!gui().fogged(un->first))
|
||||
{
|
||||
if (un->second.side() != team_num_) {
|
||||
//unit under cursor is not on our team, highlight reach
|
||||
unit_movement_resetter move_reset(un->second);
|
||||
@ -280,7 +286,8 @@ map_location mouse_handler::current_unit_attacks_from(const map_location& loc)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(current_paths_.routes.count(adj[n])) {
|
||||
if (current_paths_.destinations.contains(adj[n]))
|
||||
{
|
||||
static const size_t NDIRECTIONS = map_location::NDIRECTIONS;
|
||||
unsigned int difference = abs(int(preferred - n));
|
||||
if(difference > NDIRECTIONS/2) {
|
||||
@ -691,6 +698,7 @@ bool mouse_handler::attack_enemy_(unit_map::iterator attacker, unit_map::iterato
|
||||
|
||||
void mouse_handler::show_attack_options(unit_map::const_iterator u)
|
||||
{
|
||||
#if 0
|
||||
team& current_team = teams_[team_num_-1];
|
||||
|
||||
if(u == units_.end() || u->second.attacks_left() == 0)
|
||||
@ -702,6 +710,7 @@ void mouse_handler::show_attack_options(unit_map::const_iterator u)
|
||||
current_paths_.routes[target->first] = paths::route();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool mouse_handler::unit_in_cycle(unit_map::const_iterator it)
|
||||
|
@ -150,7 +150,7 @@ struct comp {
|
||||
|
||||
static void find_routes(const gamemap& map, const unit_map& units,
|
||||
const unit& u, const map_location& loc,
|
||||
int move_left, paths::routes_map& routes,
|
||||
int move_left, paths::dest_vect &destinations,
|
||||
std::vector<team> const &teams,
|
||||
bool force_ignore_zocs, bool allow_teleport, int turns_left,
|
||||
const team &viewing_team,
|
||||
@ -173,7 +173,7 @@ static void find_routes(const gamemap& map, const unit_map& units,
|
||||
indexer index(map.w(), map.h());
|
||||
comp node_comp(nodes);
|
||||
|
||||
int xmin = map.w(), xmax = 0, ymin = map.h(), ymax = 0;
|
||||
int xmin = loc.x, xmax = loc.x, ymin = loc.y, ymax = loc.y;
|
||||
|
||||
nodes[index(loc)] = node(move_left, turns_left, map_location::null_location, loc);
|
||||
std::vector<int> pq;
|
||||
@ -247,38 +247,67 @@ static void find_routes(const gamemap& map, const unit_map& units,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build the routes for every map_location that we reached
|
||||
for (int y = ymin; y <= ymax; ++y) {
|
||||
for (int x = xmin; x <= xmax; ++x)
|
||||
|
||||
// Build the routes for every map_location that we reached.
|
||||
// The ordering must be compatible with map_location::operator<.
|
||||
for (int x = xmin; x <= xmax; ++x) {
|
||||
for (int y = ymin; y <= ymax; ++y)
|
||||
{
|
||||
const node &n = nodes[index(map_location(x, y))];
|
||||
if (n.in - search_counter > 1u) continue;
|
||||
paths::route route;
|
||||
route.move_left = n.movement_left + n.turns_left * total_movement;
|
||||
|
||||
// the ai expects that the destination map_location not actually be in the route...
|
||||
if (n.prev.valid())
|
||||
{
|
||||
for (const node *curr = &nodes[index(n.prev)];
|
||||
curr->prev.valid(); curr = &nodes[index(curr->prev)])
|
||||
{
|
||||
assert(curr->curr.valid());
|
||||
route.steps.push_back(curr->curr);
|
||||
}
|
||||
}
|
||||
route.steps.push_back(loc);
|
||||
std::reverse(route.steps.begin(), route.steps.end());
|
||||
routes[n.curr] = route;
|
||||
paths::step s =
|
||||
{ n.curr, n.prev, n.movement_left + n.turns_left * total_movement };
|
||||
destinations.push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paths::dest_vect::const_iterator paths::dest_vect::find(const map_location &loc) const
|
||||
{
|
||||
size_t sz = size(), pos = 0;
|
||||
while (sz)
|
||||
{
|
||||
if ((*this)[pos + sz / 2].curr < loc) {
|
||||
pos = pos + sz / 2 + 1;
|
||||
sz = sz - sz / 2 - 1;
|
||||
} else sz = sz / 2;
|
||||
}
|
||||
|
||||
const_iterator i_end = end(), i = begin() + pos;
|
||||
if (i != i_end && i->curr != loc) i = i_end;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path going from the source point (included) to the
|
||||
* destination point @a j (excluded).
|
||||
*/
|
||||
std::vector<map_location> paths::dest_vect::get_path(const const_iterator &j) const
|
||||
{
|
||||
std::vector<map_location> path;
|
||||
if (!j->prev.valid()) {
|
||||
path.push_back(j->curr);
|
||||
} else {
|
||||
const_iterator i = j;
|
||||
do {
|
||||
i = find(i->prev);
|
||||
assert(i != end());
|
||||
path.push_back(i->curr);
|
||||
} while (i->prev.valid());
|
||||
}
|
||||
std::reverse(path.begin(), path.end());
|
||||
return path;
|
||||
}
|
||||
|
||||
bool paths::dest_vect::contains(const map_location &loc) const
|
||||
{
|
||||
return find(loc) != end();
|
||||
}
|
||||
|
||||
paths::paths(gamemap const &map, unit_map const &units,
|
||||
map_location const &loc, std::vector<team> const &teams,
|
||||
bool force_ignore_zoc, bool allow_teleport, const team &viewing_team,
|
||||
int additional_turns, bool see_all, bool ignore_units) :
|
||||
routes()
|
||||
int additional_turns, bool see_all, bool ignore_units)
|
||||
{
|
||||
const unit_map::const_iterator i = units.find(loc);
|
||||
if(i == units.end()) {
|
||||
@ -290,9 +319,8 @@ paths::paths(gamemap const &map, unit_map const &units,
|
||||
return;
|
||||
}
|
||||
|
||||
routes[loc].move_left = i->second.movement_left();
|
||||
find_routes(map,units,i->second,loc,
|
||||
i->second.movement_left(),routes,teams,force_ignore_zoc,
|
||||
i->second.movement_left(), destinations, teams, force_ignore_zoc,
|
||||
allow_teleport,additional_turns,viewing_team,
|
||||
see_all, ignore_units);
|
||||
}
|
||||
@ -461,18 +489,3 @@ double dummy_path_calculator::cost(const map_location&, const map_location&, con
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& outstream, const paths::route& rt) {
|
||||
outstream << "\n[route]\n\tsteps=\"";
|
||||
bool first_loop = true;
|
||||
foreach(map_location const& loc, rt.steps) {
|
||||
if(first_loop) {
|
||||
first_loop = false;
|
||||
} else {
|
||||
outstream << "->";
|
||||
}
|
||||
outstream << '(' << loc << ')';
|
||||
}
|
||||
outstream << "\"\n\tmove_left=\"" << rt.move_left << "\"\n[/route]";
|
||||
return outstream;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ struct cost_calculator
|
||||
*/
|
||||
struct paths
|
||||
{
|
||||
paths() : routes() {}
|
||||
paths() {}
|
||||
|
||||
// Construct a list of paths for the unit at loc.
|
||||
// - force_ignore_zocs: find the path ignoring ZOC entirely,
|
||||
@ -104,16 +104,20 @@ struct paths
|
||||
const team &viewing_team,int additional_turns = 0,
|
||||
bool see_all = false, bool ignore_units = false);
|
||||
|
||||
/** Structure which holds a single route between one location and another. */
|
||||
struct route
|
||||
struct step
|
||||
{
|
||||
route() : steps(), move_left(0) {}
|
||||
std::vector<map_location> steps;
|
||||
int move_left; // movement unit will have left at end of the route.
|
||||
map_location curr, prev;
|
||||
int move_left;
|
||||
};
|
||||
|
||||
typedef std::map<map_location,route> routes_map;
|
||||
routes_map routes;
|
||||
/** Ordered vector of possible destinations. */
|
||||
struct dest_vect : std::vector<step>
|
||||
{
|
||||
const_iterator find(const map_location &) const;
|
||||
bool contains(const map_location &) const;
|
||||
std::vector<map_location> get_path(const const_iterator &) const;
|
||||
};
|
||||
dest_vect destinations;
|
||||
};
|
||||
|
||||
/** Structure which holds a single route and waypoints for special events. */
|
||||
@ -135,9 +139,6 @@ struct marked_route
|
||||
waypoint_map waypoints;
|
||||
};
|
||||
|
||||
|
||||
//std::ostream& operator << (std::ostream& os, const paths::route& rt);
|
||||
|
||||
/** Structure which holds a single route between one location and another. */
|
||||
struct plain_route
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user