BWAPI
Skynet/Skynet/MapHelper.cpp
Go to the documentation of this file.
00001 #include "MapHelper.h"
00002 
00003 #include <regex>
00004 
00005 #include "UnitTracker.h"
00006 #include "Heap.h"
00007 #include "BaseTracker.h"
00008 #include "PathFinder.h"
00009 
00010 TilePosition MapHelper::spiralSearch(TilePosition startLocation, std::tr1::function<bool (TilePosition)> testFunction, int maxRadius)
00011 {
00012         int x = startLocation.x();
00013         int y = startLocation.y();
00014 
00015         int length = 1;
00016         int j      = 0;
00017         bool first = true;
00018         int dx     = 0;
00019         int dy     = 1;
00020 
00021         if(maxRadius == 0)
00022                 maxRadius = std::max(BWAPI::Broodwar->mapWidth(), BWAPI::Broodwar->mapHeight());
00023 
00024         while(length < maxRadius)
00025         {
00026                 if(x >= 0 && x < BWAPI::Broodwar->mapWidth() && y >= 0 && y < BWAPI::Broodwar->mapHeight())
00027                 {
00028                         TilePosition location(x, y);
00029                         if(testFunction(location))
00030                                 return location;
00031                 }
00032 
00033                 x = x + dx;
00034                 y = y + dy;
00035 
00036                 //count how many steps we take in this direction
00037                 ++j;
00038                 if(j == length) //if we've reached the end, its time to turn
00039                 {
00040                         //reset step counter
00041                         j = 0;
00042 
00043                         //Spiral out. Keep going.
00044                         if(!first)
00045                                 ++length; //increment step counter if needed
00046 
00047                         //first=true for every other turn so we spiral out at the right rate
00048                         first = !first;
00049 
00050                         //turn counter clockwise 90 degrees:
00051                         if (dx == 0)
00052                         {
00053                                 dx = dy;
00054                                 dy = 0;
00055                         }
00056                         else
00057                         {
00058                                 dy = -dx;
00059                                 dx = 0;
00060                         }
00061                 }
00062                 //Spiral out. Keep going.
00063         }
00064 
00065         return BWAPI::TilePositions::None;
00066 }
00067 
00068 std::set<TilePosition> MapHelper::floodFill(TilePosition start, std::tr1::function<bool (TilePosition)> testFunction, std::set<TilePosition> targets, std::set<TilePosition> ignoreTiles)
00069 {
00070         bool noTargets = targets.empty();
00071 
00072         std::set<TilePosition> remainingTiles;
00073         remainingTiles.insert(start);
00074 
00075         while(!remainingTiles.empty())
00076         {
00077                 if(!noTargets && targets.empty())
00078                         return targets;
00079 
00080                 TilePosition tile = *remainingTiles.begin();
00081 
00082                 ignoreTiles.insert(tile);
00083                 remainingTiles.erase(tile);
00084 
00085                 if(!tile.isValid())
00086                         continue;
00087 
00088                 if(!testFunction(tile))
00089                         continue;
00090 
00091                 if(noTargets)
00092                         targets.insert(tile);
00093                 else
00094                         targets.erase(tile);
00095 
00096                 if(ignoreTiles.count(TilePosition(tile.x() + 1, tile.y())) == 0)
00097                         remainingTiles.insert(TilePosition(tile.x() + 1, tile.y()));
00098                 if(ignoreTiles.count(TilePosition(tile.x() - 1, tile.y())) == 0)
00099                         remainingTiles.insert(TilePosition(tile.x() - 1, tile.y()));
00100                 if(ignoreTiles.count(TilePosition(tile.x(), tile.y() + 1)) == 0)
00101                         remainingTiles.insert(TilePosition(tile.x(), tile.y() + 1));
00102                 if(ignoreTiles.count(TilePosition(tile.x(), tile.y() - 1)) == 0)
00103                         remainingTiles.insert(TilePosition(tile.x(), tile.y() - 1));
00104         }
00105 
00106         return targets;
00107 }
00108 
00109 std::map<WalkPosition, int> MapHelper::walkSearch(WalkPosition start, std::tr1::function<bool (WalkPosition)> testFunction, std::set<WalkPosition> targets, std::set<WalkPosition> ignoreTiles)
00110 {
00111         std::map<WalkPosition, int> returnDistances;
00112 
00113         int mapWidth = BWAPI::Broodwar->mapWidth() * 4;
00114         int mapHeight = BWAPI::Broodwar->mapHeight() * 4;
00115 
00116         Heap<WalkPosition, int> openTiles(true);
00117         std::map<WalkPosition, int> gmap;
00118         std::set<WalkPosition> closedTiles;
00119 
00120         openTiles.push(std::make_pair(start, 0));
00121         gmap[start] = 0;
00122 
00123         int maxhvalue = std::max(mapHeight, mapWidth);
00124 
00125         while(!openTiles.empty())
00126         {
00127                 WalkPosition p = openTiles.top().first;
00128 
00129                 int fvalue = openTiles.top().second;
00130                 int gvalue = gmap[p];
00131 
00132                 openTiles.pop();
00133                 closedTiles.insert(p);
00134                 returnDistances[p] = gvalue;
00135 
00136                 for(int i = 0; i < 4; ++i)
00137                 {
00138                         int x = i == 0 ? 1 : i == 1 ? -1 : 0;
00139                         int y = i == 2 ? 1 : i == 3 ? -1 : 0;
00140                         WalkPosition tile(p.x + x, p.y + y);
00141 
00142                         if(tile.x < 0 || tile.y < 0 || tile.x >= mapWidth || tile.y >= mapHeight)
00143                                 continue;
00144 
00145                         if(closedTiles.find(tile) != closedTiles.end())
00146                                 continue;
00147 
00148                         if(!testFunction(tile))
00149                                 continue;
00150 
00151                         int g = gvalue + 1;
00152 
00153                         int f = g;
00154                         if(gmap.find(tile) == gmap.end() || gmap[tile] > g)
00155                         {
00156                                 gmap[tile] = g;
00157                                 openTiles.set(tile, f);
00158                         }
00159                 }
00160         }
00161 
00162         return returnDistances;
00163 }
00164 
00165 bool MapHelper::isAnyVisible(TilePosition location, BWAPI::UnitType type)
00166 {
00167         for(int x = location.x(); x < location.x() + type.tileWidth(); ++x)
00168         {
00169                 for(int y = location.y(); y < location.y() + type.tileHeight(); ++y)
00170                 {
00171                         if(BWAPI::Broodwar->isVisible(x, y))
00172                                 return true;
00173                 }
00174         }
00175 
00176         return false;
00177 }
00178 
00179 bool MapHelper::isAllVisible(TilePosition location, BWAPI::UnitType type)
00180 {
00181         for(int x = location.x(); x < location.x() + type.tileWidth(); ++x)
00182         {
00183                 for(int y = location.y(); y < location.y() + type.tileHeight(); ++y)
00184                 {
00185                         if(!BWAPI::Broodwar->isVisible(x, y))
00186                                 return false;
00187                 }
00188         }
00189 
00190         return true;
00191 }
00192 
00193 bool MapHelper::isTileWalkable(TilePosition location)
00194 {
00195         return isTileWalkable(location.x(), location.y());
00196 }
00197 
00198 bool MapHelper::isTileWalkable(int x, int y)
00199 {
00200         for(int nx = x * 4; nx < x * 4 + 4; ++nx)
00201         {
00202                 for(int ny = y * 4; ny < y * 4 + 4; ++ny)
00203                 {
00204                         if(!BWAPI::Broodwar->isWalkable(nx, ny))
00205                                 return false;
00206                 }
00207         }
00208 
00209         return true;
00210 }
00211 
00212 bool MapHelper::mapIs(std::string name)
00213 {
00214         std::string mapName = BWAPI::Broodwar->mapName();
00215         std::transform(mapName.begin(), mapName.end(), mapName.begin(), tolower);
00216 
00217         std::string mapFileName = BWAPI::Broodwar->mapFileName();
00218         std::transform(mapFileName.begin(), mapFileName.end(), mapFileName.begin(), tolower);
00219 
00220         std::transform(name.begin(), name.end(), name.begin(), tolower);
00221 
00222         return std::tr1::regex_search(mapName.begin(), mapName.end(), std::tr1::regex(name)) || std::tr1::regex_search(mapFileName.begin(), mapFileName.end(), std::tr1::regex(name));
00223 }
00224 
00225 int MapHelper::getGroundDistance(Position start, Position end)
00226 {
00227         if(!BWAPI::Broodwar->hasPath(start, end))
00228                 return std::numeric_limits<int>::max();
00229 
00230         int groundDistance = PathFinder::Instance().CreateCheapWalkPath(start, end).getLength();
00231         int linearDistance = start.getApproxDistance(end);
00232 
00233         if(groundDistance < linearDistance)
00234                 return linearDistance;
00235 
00236         return groundDistance;
00237 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines