BWAPI
BasicAIModule/source/EnhancedSide.cpp
Go to the documentation of this file.
00001 
00002 /*
00003 * EnhancedSide.cpp
00004 */
00005 #include "EnhancedSide.h"
00006 
00007 #include <BWAPI.h>
00008 #include <BWTA.h>
00009 
00010 #include <assert.h>
00011 
00012 using std::pair;
00013 using std::vector;
00014 
00015 EnhancedSide::EnhancedSide(pair<BWAPI::Position, BWAPI::Position> endPoints, Orientation orientation)
00016 {
00017         bool xMatch, yMatch;
00018         bool down, right;
00019         BWAPI::TilePosition * startTile, * endTile;
00020         BWAPI::TilePosition currTile;
00021 
00022         down = right = false;
00023 
00024         xMatch = (endPoints.first.x() == endPoints.second.x());
00025         yMatch = (endPoints.first.y() == endPoints.second.y());
00026 
00027         /* ensure points share an x or y value */
00028         assert( xMatch || yMatch );
00029 
00030         /* set our endPoints */
00031         this->endPoints = endPoints;
00032         this->orientation = orientation;
00033 
00034         if (orientation == top || orientation == bottom) {
00035                 horizontal = true;
00036         }
00037         else {
00038                 horizontal = false;
00039         }
00040 
00041         /* get the end point tile positions */
00042         endTilePositions.first = BWAPI::TilePosition(endPoints.first);
00043         endTilePositions.second = BWAPI::TilePosition(endPoints.second);
00044 
00045         /* check to see if same tile, this is OK */
00046         if (endTilePositions.first == endTilePositions.second) {
00047                 tilePositions.push_back(endTilePositions.first);
00048                 /* nothing else to do */
00049                 return;
00050         }
00051 
00052         /* establish the start tile position and move down or right */
00053         if (yMatch) { // move on x
00054 
00055                 right = true;
00056 
00057                 if (endTilePositions.first.x() < endTilePositions.second.x()) {
00058                         startTile = &endTilePositions.first;
00059                         endTile = &endTilePositions.second;
00060                 }
00061                 else {
00062                         startTile = &endTilePositions.second;
00063                         endTile = &endTilePositions.first;
00064                 }
00065         }
00066         else { // move on y
00067 
00068                 down = true;
00069 
00070                 if (endTilePositions.first.y() < endTilePositions.second.y()) {
00071                         startTile = &endTilePositions.first;
00072                         endTile = &endTilePositions.second;
00073                 }
00074                 else {
00075                         startTile = &endTilePositions.second;
00076                         endTile = &endTilePositions.first;
00077                 }
00078         }
00079 
00080         /* add tiles in order */
00081         tilePositions.push_back(*startTile);
00082         currTile = *startTile;
00083 
00084         while (currTile != *endTile) {
00085 
00086                 if (right) {
00087                         currTile.x() += 1;
00088                 }
00089                 else {
00090                         currTile.y() += 1;
00091                 }
00092                 tilePositions.push_back(currTile);
00093         }
00094         /* endTile will already be added, don't add again! */
00095 
00096 }
00097 
00098 EnhancedSide::~EnhancedSide(void)
00099 {
00100 }
00101 
00102 pair<BWAPI::Position, BWAPI::Position> EnhancedSide::getEndPoints()
00103 {
00104         return endPoints;
00105 }
00106 vector<BWAPI::TilePosition> EnhancedSide::getTilePositions()
00107 {
00108         return tilePositions;
00109 }
00110 EnhancedSide::Orientation EnhancedSide::getOrientation(void)
00111 {
00112         return orientation;
00113 }
00114 bool EnhancedSide::isHorizontal(void)
00115 {
00116         return horizontal;
00117 }
00118 // returns length not covered / overlapping and if not zero sets the leftover
00119 // sides not covered in sidesNotCovered, unless NULL, then only returns the 
00120 // length not covered
00121 int EnhancedSide::checkCoverage(EnhancedSide coveringSide, vector<EnhancedSide> * sidesNotCovered)
00122 {
00123 
00124         int lengthNotCovered = 0;
00125         int xLeft, xRight, xCovLeft, xCovRight;
00126         int yTop, yBottom, yCovTop, yCovBottom;
00127         int diff;
00128         pair<BWAPI::Position, BWAPI::Position> newEndPoints;
00129         bool getSides;
00130 
00131         // must be parallel
00132         if (coveringSide.horizontal != horizontal) {
00133                 return -1;
00134         }
00135 
00136         getSides = true;
00137 
00138         if (sidesNotCovered == NULL) {
00139                 getSides = false;
00140         }
00141 
00142         xLeft = endPoints.first.x();
00143         xRight = endPoints.second.x();
00144         xCovLeft = coveringSide.endPoints.first.x();
00145         xCovRight = coveringSide.endPoints.second.x();
00146 
00147         yTop = endPoints.first.y();
00148         yBottom = endPoints.second.y();
00149         yCovTop = coveringSide.endPoints.first.y();
00150         yCovBottom = coveringSide.endPoints.second.x();
00151 
00152         // if horizontal compare x
00153         if (horizontal) {
00154                 // check left end
00155                 if (xCovLeft > xLeft) {
00156                         diff = xCovLeft - xLeft;
00157                         lengthNotCovered += diff;
00158                         if (getSides) {
00159                                 newEndPoints.first.x() = xLeft;
00160                                 newEndPoints.second.x() = xCovLeft;
00161                                 // use y val and orientation of the side trying to cover
00162                                 newEndPoints.first.y() = yTop;
00163                                 newEndPoints.second.y() = yTop;
00164                                 sidesNotCovered->push_back(EnhancedSide(newEndPoints, orientation));
00165                         }
00166                 }
00167 
00168                 // check right end
00169                 if (xCovRight < xRight) {
00170                         diff = xRight - xCovRight;
00171                         lengthNotCovered += diff;
00172                         if (getSides) {
00173                                 newEndPoints.first.x() = xCovRight;
00174                                 newEndPoints.second.x() = xRight;
00175                                 // use y val and orientation of the side trying to cover
00176                                 newEndPoints.first.y() = yTop;
00177                                 newEndPoints.second.y() = yTop;
00178                                 sidesNotCovered->push_back(EnhancedSide(newEndPoints, orientation));
00179                         }
00180                 }
00181         }
00182 
00183         // if vertical compare y
00184         else {
00185                 // check top end
00186                 if (yCovTop > yTop) {
00187                         diff = yCovTop - yTop;
00188                         lengthNotCovered += diff;
00189                         if (getSides) {
00190                                 newEndPoints.first.y() = yTop;
00191                                 newEndPoints.second.y() = yCovTop;
00192                                 // use x val and orientation of the side trying to cover
00193                                 newEndPoints.first.x() = xLeft;
00194                                 newEndPoints.second.x() = xLeft;
00195                                 sidesNotCovered->push_back(EnhancedSide(newEndPoints, orientation));
00196                         }
00197                 }
00198 
00199                 // check bottom end
00200                 if (yCovBottom < yBottom) {
00201                         diff = yBottom - yCovBottom;
00202                         lengthNotCovered += diff;
00203                         if (getSides) {
00204                                 newEndPoints.first.y() = yCovBottom;
00205                                 newEndPoints.second.y() = yBottom;
00206                                 // use x val and orientation of the side trying to cover
00207                                 newEndPoints.first.x() = xLeft;
00208                                 newEndPoints.second.x() = xLeft;
00209                                 sidesNotCovered->push_back(EnhancedSide(newEndPoints, orientation));
00210                         }
00211                 }
00212         }
00213 
00214         return lengthNotCovered;
00215 }
00216 
00217 // finds minimum gap between a side and a wall by searching for buildable tiles
00218 // returns the minimum number of tiles found
00219 // It's a fine grained assessment, searching with canBuildHere() should be done
00220 // before calling this function.
00221 // This function will let you know if you need to shift all your build places 
00222 // as a group or it will tell you if this arrangement is better than another.
00223 int EnhancedSide::checkGap()
00224 {
00225         vector<BWAPI::TilePosition> tiles = this->getTilePositions();
00226         BWAPI::TilePosition currentTile;
00227         int tileLength = (int)tiles.size();
00228         int xDir, yDir;
00229         int currentNumTiles;
00230         int minNumTiles = 0;
00231         bool unbuildableTileNotFound;
00232 
00233         // get xDir and yDir based on orientation
00234         if (orientation == EnhancedSide::left) {
00235                 xDir = -1;
00236                 yDir = 0;
00237         }
00238         else if (orientation == EnhancedSide::top) {
00239                 xDir = 0;
00240                 yDir = -1;
00241         }
00242         else if (orientation == EnhancedSide::right) {
00243                 xDir = +1;
00244                 yDir = 0;
00245         }
00246         else if (orientation == EnhancedSide::bottom) {
00247                 xDir = 0;
00248                 yDir = +1;
00249         }
00250 
00251         for (int m = 0; m < tileLength; ++m) {
00252                 currentTile = tiles[m];
00253                 // reset
00254                 unbuildableTileNotFound = true;
00255                 currentNumTiles = 0;
00256 
00257                 while (unbuildableTileNotFound) {
00258                         // increment
00259                         currentTile.x() += xDir;
00260                         currentTile.y() += yDir;
00261 
00262                         // check tile
00263                         if (BWAPI::Broodwar->isBuildable(currentTile, true)) {
00264                                 // add to this rounds gap
00265                                 currentNumTiles++;
00266                         }
00267                         else {
00268                                 // found the wall
00269                                 unbuildableTileNotFound = false;
00270                                 break;
00271                         }
00272                 }
00273 
00274                 // check for minimum
00275                 if (m == 0) {
00276                         minNumTiles = currentNumTiles;
00277                 }
00278                 else if (currentNumTiles < minNumTiles) {
00279                         minNumTiles = currentNumTiles;
00280                 }
00281         }
00282 
00283         return minNumTiles;
00284 }
00285 /* draws a line */
00286 void EnhancedSide::drawSide(BWAPI::Color color)
00287 {
00288         BWAPI::Broodwar->drawLineMap(endPoints.first.x(), endPoints.first.y(), 
00289                 endPoints.second.x(), endPoints.second.y(), color); 
00290 }
00291 /* draws all the individual tiles for that side */
00292 void EnhancedSide::drawTiles(BWAPI::Color color)
00293 {
00294         EnhancedUI * eui = new EnhancedUI();
00295         for (int m = 0; m < (int) tilePositions.size(); ++m) {
00296                 eui->drawTilePosition(tilePositions[m], color);
00297         }
00298         delete(eui);
00299 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines