BWAPI
Skynet/Skynet/UnitHelper.cpp
Go to the documentation of this file.
00001 #include "UnitHelper.h"
00002 
00003 #include <algorithm>
00004 
00005 bool UnitHelper::unitProducesGround(BWAPI::UnitType type)
00006 {
00007         static std::set<BWAPI::UnitType> unitData;
00008         if(unitData.empty())
00009         {
00010                 for each(BWAPI::UnitType type in BWAPI::UnitTypes::allUnitTypes())
00011                 {
00012                         if(!type.isFlyer() && type.whatBuilds().first.isBuilding())
00013                                 unitData.insert(type.whatBuilds().first);
00014                 }
00015         }
00016 
00017         return unitData.count(type) != 0;
00018 }
00019 
00020 class ClusterCompare
00021 {
00022 public:
00023         ClusterCompare(size_t minSize)
00024                 : mMinSize(minSize)
00025         {}
00026 
00027         bool operator()(const UnitGroup &set)
00028         {
00029                 return set.empty() || set.size() < mMinSize;
00030         }
00031 
00032         size_t mMinSize;
00033 };
00034 
00035 std::vector<UnitGroup> UnitHelper::getClusters(const UnitGroup &units, int distance, int minSize)
00036 {
00037         std::vector<UnitGroup> clusters;
00038 
00039         for each(Unit unit in units)
00040         {
00041                 std::vector<size_t> clustersInRange;
00042                 for(size_t i = 0; i < clusters.size(); ++i)
00043                 {
00044                         for each(Unit clusterUnit in clusters[i])
00045                         {
00046                                 if(unit->getPosition().getApproxDistance(clusterUnit->getPosition()) <= distance)
00047                                 {
00048                                         clustersInRange.push_back(i);
00049                                         break;
00050                                 }
00051                         }
00052                 }
00053 
00054                 if(clustersInRange.empty())
00055                 {
00056                         UnitGroup newCluster;
00057                         newCluster.insert(unit);
00058                         clusters.push_back(newCluster);
00059                 }
00060                 else
00061                 {
00062                         clusters[clustersInRange[0]].insert(unit);
00063 
00064                         for(size_t i = 1; i < clustersInRange.size(); ++i)
00065                         {
00066                                 for each(Unit clusterUnit in clusters[clustersInRange[i]])
00067                                 {
00068                                         clusters[clustersInRange[0]].insert(clusterUnit);
00069                                 }
00070                                 clusters[clustersInRange[i]].clear();
00071                         }
00072                 }
00073         }
00074 
00075         clusters.erase(std::remove_if(clusters.begin(), clusters.end(), ClusterCompare(minSize)), clusters.end());
00076 
00077         return clusters;
00078 }
00079 
00080 bool UnitHelper::hasAddon(BWAPI::UnitType type) 
00081 {
00082         return(type == BWAPI::UnitTypes::Terran_Command_Center ||
00083                 type == BWAPI::UnitTypes::Terran_Factory || 
00084                 type == BWAPI::UnitTypes::Terran_Starport ||
00085                 type == BWAPI::UnitTypes::Terran_Science_Facility);
00086 }
00087 
00088 Position UnitHelper::tileToPosition(TilePosition tile, BWAPI::UnitType type)
00089 {
00090         return Position(tile.x()*32+(type.tileWidth()*16), tile.y()*32+(type.tileHeight()*16));
00091 }
00092 
00093 bool UnitHelper::isStaticDefense(BWAPI::UnitType type)
00094 {
00095         return(type == BWAPI::UnitTypes::Protoss_Photon_Cannon ||
00096                 type == BWAPI::UnitTypes::Zerg_Creep_Colony ||
00097                 type == BWAPI::UnitTypes::Zerg_Spore_Colony ||
00098                 type == BWAPI::UnitTypes::Zerg_Sunken_Colony ||
00099                 type == BWAPI::UnitTypes::Terran_Bunker ||
00100                 type == BWAPI::UnitTypes::Terran_Missile_Turret);
00101 }
00102 
00103 bool UnitHelper::isArmyUnit(BWAPI::UnitType type)
00104 {
00105         if(type.isBuilding())
00106                 return false;
00107         if(type.isSpell())
00108                 return false;
00109         if(type.isWorker())
00110                 return false;
00111         if(type == BWAPI::Broodwar->self()->getRace().getSupplyProvider())
00112                 return false;
00113         if(type == BWAPI::UnitTypes::Zerg_Egg)
00114                 return false;
00115         if(type == BWAPI::UnitTypes::Protoss_Interceptor)
00116                 return false;
00117         if(type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine)
00118                 return false;
00119         if(type == BWAPI::UnitTypes::Zerg_Larva)
00120                 return false;
00121         if(type == BWAPI::UnitTypes::Protoss_Scarab)
00122                 return false;
00123         if(type == BWAPI::UnitTypes::Protoss_Observer)
00124                 return false;
00125 
00126         return true;
00127 }
00128 
00129 int UnitHelper::getDistance(const Position &pos1, const BWAPI::UnitType type1, const Position &pos2, const BWAPI::UnitType type2)
00130 {
00131         const int uLeft       = pos1.x() - type1.dimensionLeft();
00132         const int uTop        = pos1.y() - type1.dimensionUp();
00133         const int uRight      = pos1.x() + type1.dimensionRight() + 1;
00134         const int uBottom     = pos1.y() + type1.dimensionDown() + 1;
00135 
00136         const int targLeft    = pos2.x() - type2.dimensionLeft();
00137         const int targTop     = pos2.y() - type2.dimensionUp();
00138         const int targRight   = pos2.x() + type2.dimensionRight() + 1;
00139         const int targBottom  = pos2.y() + type2.dimensionDown() + 1;
00140 
00141         int xDist = uLeft - targRight;
00142         if(xDist < 0)
00143         {
00144                 xDist = targLeft - uRight;
00145                 if(xDist < 0)
00146                         xDist = 0;
00147         }
00148 
00149         int yDist = uTop - targBottom;
00150         if(yDist < 0)
00151         {
00152                 yDist = targTop - uBottom;
00153                 if(yDist < 0)
00154                         yDist = 0;
00155         }
00156 
00157         return Position(0, 0).getApproxDistance(Position(xDist, yDist));
00158 }
00159 
00160 int UnitHelper::getDistance(const Position &pos1, const BWAPI::UnitType type1, const Position &pos2)
00161 {
00162         const int uLeft       = pos1.x() - type1.dimensionLeft();
00163         const int uTop        = pos1.y() - type1.dimensionUp();
00164         const int uRight      = pos1.x() + type1.dimensionRight() + 1;
00165         const int uBottom     = pos1.y() + type1.dimensionDown() + 1;
00166 
00167         int xDist = uLeft - (pos2.x() + 1);
00168         if(xDist < 0)
00169         {
00170                 xDist = pos2.x() - uRight;
00171                 if(xDist < 0)
00172                         xDist = 0;
00173         }
00174 
00175         int yDist = uTop - (pos2.y() + 1);
00176         if(yDist < 0)
00177         {
00178                 yDist = pos2.y() - uBottom;
00179                 if(yDist < 0)
00180                         yDist = 0;
00181         }
00182 
00183         return Position(0, 0).getApproxDistance(Position(xDist, yDist));
00184 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines