Fixed find_vacant_tile looking for tiles outside the map.

(Fix for bug #15774.)

Sped up the code along the way.
This commit is contained in:
Guillaume Melquiond 2010-04-05 06:00:03 +00:00
parent 8119629789
commit 38d1c25baa

View File

@ -44,43 +44,42 @@ map_location pathfind::find_vacant_tile(const gamemap& map,
pathfind::VACANT_TILE_TYPE vacancy, pathfind::VACANT_TILE_TYPE vacancy,
const unit* pass_check) const unit* pass_check)
{ {
std::set<map_location> pending_tiles_to_check; if (!map.on_board(loc)) return map_location();
std::set<map_location> tiles_checked; std::set<map_location> pending_tiles_to_check, tiles_checked;
pending_tiles_to_check.insert(loc); pending_tiles_to_check.insert(loc);
// Iterate out 50 hexes from loc // Iterate out 50 hexes from loc
for (int distance = 0; distance < 50; ++distance) { for (int distance = 0; distance < 50; ++distance) {
if (pending_tiles_to_check.empty()) if (pending_tiles_to_check.empty())
return map_location(); return map_location();
//Copy over the hexes to check and clear the old set //Copy over the hexes to check and clear the old set
std::set<map_location> tiles_checking = pending_tiles_to_check; std::set<map_location> tiles_checking;
std::set<map_location>::const_iterator tc_itor = tiles_checking.begin(); tiles_checking.swap(pending_tiles_to_check);
pending_tiles_to_check.clear();
//Iterate over all the hexes we need to check //Iterate over all the hexes we need to check
for ( ; tc_itor != tiles_checking.end(); ++tc_itor ) foreach (const map_location &loc, tiles_checking)
{ {
//If the unit cannot reach this area or it's not a castle but should, skip it. //If the unit cannot reach this area or it's not a castle but should, skip it.
if ((vacancy == pathfind::VACANT_CASTLE && !map.is_castle(*tc_itor)) if ((vacancy == pathfind::VACANT_CASTLE && !map.is_castle(loc))
|| (pass_check && pass_check->movement_cost(map[*tc_itor]) || (pass_check && pass_check->movement_cost(map[loc])
== unit_movement_type::UNREACHABLE)) == unit_movement_type::UNREACHABLE))
continue; continue;
//If the hex is empty, return it. //If the hex is empty, return it.
if (map.on_board(*tc_itor) && units.find(*tc_itor) == units.end()) if (units.find(loc) == units.end())
return (*tc_itor); return loc;
map_location adjs[6]; map_location adjs[6];
get_adjacent_tiles(*tc_itor,adjs); get_adjacent_tiles(loc,adjs);
for (int i = 0; i != 6; ++i) foreach (const map_location &loc, adjs)
{ {
//Add the tile to be checked if it hasn't already been and isn't already if (!map.on_board(loc)) continue;
//pending to be checked // Add the tile to be checked if it hasn't already been and
if (pending_tiles_to_check.find(adjs[i]) == pending_tiles_to_check.end() && // isn't being checked.
tiles_checked.find(adjs[i]) == tiles_checked.end() && if (tiles_checked.find(loc) == tiles_checked.end() &&
tiles_checking.find(adjs[i]) == tiles_checking.end()) tiles_checking.find(loc) == tiles_checking.end())
{ {
pending_tiles_to_check.insert(adjs[i]); pending_tiles_to_check.insert(loc);
} }
} }
} }
tiles_checked = tiles_checking; tiles_checked.swap(tiles_checking);
} }
return map_location(); return map_location();
} }