Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "global.hpp"
00022
00023 #include "pathutils.hpp"
00024
00025 #include "map.hpp"
00026
00027 void get_tile_ring(const map_location& a, const int r, std::vector<map_location>& res)
00028 {
00029 if(r <= 0) {
00030 return;
00031 }
00032
00033 map_location loc = a.get_direction(map_location::SOUTH_WEST, r);
00034
00035 for(int n = 0; n != 6; ++n) {
00036 const map_location::DIRECTION dir = static_cast<map_location::DIRECTION>(n);
00037 for(int i = 0; i != r; ++i) {
00038 res.push_back(loc);
00039 loc = loc.get_direction(dir, 1);
00040 }
00041 }
00042 }
00043
00044 void get_tiles_in_radius(const map_location& a, const int r, std::vector<map_location>& res)
00045 {
00046 for(int n = 0; n <= r; ++n) {
00047 get_tile_ring(a, n, res);
00048 }
00049 }
00050
00051 static void get_tiles_radius_internal(const map_location& a, size_t radius,
00052 std::set<map_location>& res, std::map<map_location,int>& visited)
00053 {
00054 visited[a] = radius;
00055 res.insert(a);
00056
00057 if(radius == 0) {
00058 return;
00059 }
00060
00061 map_location adj[6];
00062 get_adjacent_tiles(a,adj);
00063 for(size_t i = 0; i != 6; ++i) {
00064 if(visited.count(adj[i]) == 0 || visited[adj[i]] < int(radius)-1) {
00065 get_tiles_radius_internal(adj[i],radius-1,res,visited);
00066 }
00067 }
00068 }
00069
00070 void get_tiles_radius(const map_location& a, size_t radius,
00071 std::set<map_location>& res)
00072 {
00073 std::map<map_location,int> visited;
00074 get_tiles_radius_internal(a,radius,res,visited);
00075 }
00076
00077 void get_tiles_radius(gamemap const &map, std::vector<map_location> const &locs,
00078 size_t radius, std::set<map_location> &res, bool with_border,
00079 xy_pred *pred)
00080 {
00081 typedef std::set<map_location> location_set;
00082 location_set not_visited(locs.begin(), locs.end()), must_visit, filtered_out;
00083 ++radius;
00084
00085 for(;;) {
00086 location_set::const_iterator it = not_visited.begin(), it_end = not_visited.end();
00087 std::copy(it,it_end,std::inserter(res,res.end()));
00088 for(; it != it_end; ++it) {
00089 map_location adj[6];
00090 get_adjacent_tiles(*it, adj);
00091 for(size_t i = 0; i != 6; ++i) {
00092 map_location const &loc = adj[i];
00093 if ( with_border ? map.on_board_with_border(loc) :
00094 map.on_board(loc) ) {
00095 if ( !res.count(loc) && !filtered_out.count(loc) ) {
00096 if ( !pred || (*pred)(loc) )
00097 must_visit.insert(loc);
00098 else
00099 filtered_out.insert(loc);
00100 }
00101 }
00102 }
00103 }
00104
00105 if(--radius == 0 || must_visit.empty()) {
00106 break;
00107 }
00108
00109 not_visited.swap(must_visit);
00110 must_visit.clear();
00111 }
00112 }
00113