BWAPI
BasicAIModule/source/EnhancedChokepoint.cpp
Go to the documentation of this file.
00001 /*
00002 * EnhancedChokepoint.cpp
00003 */
00004 #include "EnhancedChokepoint.h"
00005 
00006 #include <BWAPI.h>
00007 #include <BWTA.h>
00008 
00009 #include <assert.h>
00010 
00011 using std::pair;
00012 using std::vector;
00013 
00014 
00015 EnhancedChokepoint::EnhancedChokepoint(BWTA::Chokepoint * chokepoint)
00016 {
00017         pair<BWAPI::Position, BWAPI::Position> sides;
00018         /* corners */
00019         BWAPI::Position topLeft, topRight, bottomLeft, bottomRight;
00020         /* sides */
00021         pair<BWAPI::Position, BWAPI::Position> leftSide, topSide, rightSide, bottomSide;
00022         /* regions */
00023         pair<BWTA::Region *, BWTA::Region *> regions;
00024 
00025         assert(chokepoint);
00026         cp = chokepoint;
00027 
00028         regions = cp->getRegions();
00029         sides = cp->getSides();
00030 
00031         /* get tile positions for center & sides */
00032         tPosCenter = BWAPI::TilePosition(cp->getCenter());
00033         tPosSides.first = BWAPI::TilePosition(sides.first);
00034         tPosSides.second = BWAPI::TilePosition(sides.second);
00035 
00036         /* get bounding box in position coords by tile positions */
00037 
00038         if(tPosSides.first.x() <= tPosSides.second.x()) {
00039                 xLeft = tPosSides.first.x() * 32;
00040                 xRight = ((tPosSides.second.x() + 1) * 32) - 1;
00041         }
00042         else {
00043                 xLeft = tPosSides.second.x() * 32;
00044                 xRight = ((tPosSides.first.x() + 1) * 32) - 1;
00045         }
00046 
00047         if(tPosSides.first.y() <= tPosSides.second.y()) {
00048                 yTop = tPosSides.first.y() * 32;
00049                 yBottom = ((tPosSides.second.y() + 1) * 32) - 1;
00050         }
00051         else {
00052                 yTop = tPosSides.second.y() * 32;
00053                 yBottom = ((tPosSides.first.y() + 1) * 32) - 1;
00054         }
00055 
00056         /* set corner positions */
00057         topLeft = BWAPI::Position(xLeft, yTop);
00058         topRight = BWAPI::Position(xRight, yTop);
00059         bottomLeft = BWAPI::Position(xLeft, yBottom);
00060         bottomRight = BWAPI::Position(xRight, yBottom);
00061 
00062         /* set sides, first position must be less
00063         * than the second (x or y), for searching purposes,
00064         * ie, only search right or down
00065         */
00066         leftSide.first = topLeft;
00067         leftSide.second = bottomLeft;
00068         rightSide.first = topRight;
00069         rightSide.second = bottomRight;
00070         topSide.first = topLeft;
00071         topSide.second = topRight;
00072         bottomSide.first = bottomLeft;
00073         bottomSide.second = bottomRight;
00074 
00075         /* search for sides in region A */
00076         regionASides.first = regions.first;
00077         regionABuildableTiles.first = regions.first;
00078         regionABuildTile.first = regions.first; 
00079 
00080         if (isSideInRegion(leftSide, regions.first)) {
00081                 regionASides.second.push_back(EnhancedSide(leftSide, EnhancedSide::left));
00082         }
00083         if (isSideInRegion(topSide, regions.first)) {
00084                 regionASides.second.push_back(EnhancedSide(topSide, EnhancedSide::top));
00085         }
00086         if (isSideInRegion(rightSide, regions.first)) {
00087                 regionASides.second.push_back(EnhancedSide(rightSide, EnhancedSide::right));
00088         }
00089         if (isSideInRegion(bottomSide, regions.first)) {
00090                 regionASides.second.push_back(EnhancedSide(bottomSide, EnhancedSide::bottom));
00091         }
00092 
00093 
00094         /* serach for sides in region B */
00095         regionBSides.first = regions.second;
00096         regionBBuildableTiles.first = regions.second;
00097         regionBBuildTile.first = regions.second; 
00098 
00099         if (isSideInRegion(leftSide, regions.second)) {
00100                 regionBSides.second.push_back(EnhancedSide(leftSide, EnhancedSide::left));
00101         }
00102         if (isSideInRegion(topSide, regions.second)) {
00103                 regionBSides.second.push_back(EnhancedSide(topSide, EnhancedSide::top));
00104         }
00105         if (isSideInRegion(rightSide, regions.second)) {
00106                 regionBSides.second.push_back(EnhancedSide(rightSide, EnhancedSide::right));
00107         }
00108         if (isSideInRegion(bottomSide, regions.second)) {
00109                 regionBSides.second.push_back(EnhancedSide(bottomSide, EnhancedSide::bottom));
00110         }
00111 
00112         // search buildable tiles for each region 
00113         radialSweepSearch(regionASides);
00114         radialSweepSearch(regionBSides);
00115 
00116 }
00117 
00118 EnhancedChokepoint::~EnhancedChokepoint()
00119 {
00120 }
00121 
00122 /* wrapper Chokepoint functions */
00123 const pair<BWTA::Region *, BWTA::Region *> & EnhancedChokepoint::getRegions() 
00124 {
00125         return cp->getRegions();
00126 }
00127 
00128 const pair<BWAPI::Position, BWAPI::Position> & EnhancedChokepoint::getSides() 
00129 {
00130         return cp->getSides();
00131 }
00132 
00133 BWAPI::Position EnhancedChokepoint::getCenter() 
00134 {
00135         return cp->getCenter();
00136 }
00137 
00138 double EnhancedChokepoint::getWidth() 
00139 {
00140         return cp->getWidth();
00141 }
00142 
00143 
00144 
00145 /* enhanced functions */
00146 
00147 // http://alienryderflex.com/polygon/
00148 //  Globals which should be set before calling this function:
00149 //
00150 //  int    polySides  =  how many corners the polygon has
00151 //  float  polyX[]    =  horizontal coordinates of corners
00152 //  float  polyY[]    =  vertical coordinates of corners
00153 //  float  x, y       =  point to be tested
00154 //
00155 //  (Globals are used in this example for purposes of speed.  Change as
00156 //  desired.)
00157 //
00158 //  The function will return YES if the point x,y is inside the polygon, or
00159 //  NO if it is not.  If the point is exactly on the edge of the polygon,
00160 //  then the function may return YES or NO.
00161 //
00162 //  Note that division by zero is avoided because the division is protected
00163 //  by the "if" clause which surrounds it.
00164 bool EnhancedChokepoint::isPositionInPolygon(BWAPI::Position searchPos, BWTA::Polygon poly){
00165 
00166         int numPositions = (int) poly.size();
00167         int polySides = numPositions;
00168         vector<float>polyX;
00169         vector<float>polyY;
00170         float x, y;
00171         int      i, j;
00172         bool  oddNodes = false;
00173         BWAPI::Position pos;
00174 
00175         polyX.reserve(numPositions);
00176         polyY.reserve(numPositions);
00177 
00178         /* get position values from polygon */
00179         for (int m = 0; m < numPositions; ++m) {
00180                 pos = poly[m];
00181                 polyX.push_back((float) pos.x());
00182                 polyY.push_back((float) pos.y());
00183         }
00184 
00185         /* get position to search for */
00186         x = (float) searchPos.x();
00187         y = (float) searchPos.y();
00188 
00189 
00190         /* init j */
00191         j = polySides - 1;
00192 
00193         for (i=0; i<polySides; i++) {
00194                 if ((polyY[i]< y && polyY[j]>=y
00195                         ||   polyY[j]< y && polyY[i]>=y)
00196                         &&  (polyX[i]<=x || polyX[j]<=x)) {
00197                                 oddNodes^=(polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x); }
00198                 j=i; }
00199 
00200         return oddNodes; 
00201 }
00202 
00203 // used to find buildable tiles and a build tile for a supply depot
00204 void EnhancedChokepoint::radialSweepSearch(pair<BWTA::Region * , vector<EnhancedSide>> regionSides)
00205 {
00206 
00207         int numSides;
00208         //      # of rounds to creep out
00209         int radiusLevel;
00210         // directions -1, +1, or 0
00211         int xDir, yDir;
00212         // used to find new start tile from
00213         // previous stat tile
00214         int xStartDir, yStartDir;
00215         bool horizontalSide;
00216         // stores if horizontal, xDir, and yDir
00217         // mainly to reset to the initial direction
00218         // state, but also if start tile ends up being
00219         // on a different side
00220         // side 0 state:
00221         // directionOfSides[0][0] = is horizontal
00222         // directionOfSides[0][1] = xDir
00223         // directionOfSides[0][2] = yDir
00224         vector<int>sideDirection;
00225         vector<vector<int>> directionOfSides;
00226         bool foundBuildTile;
00227         bool foundStartTile;
00228         bool lastTileBuildable;
00229         EnhancedSide::Orientation orientation;
00230         // what we are searching for, includes all
00231         // buildable tiles found in the search
00232         vector<BWAPI::TilePosition> buildableTiles;
00233         BWAPI::TilePosition buildTile;
00234         // last known good buildable tile
00235         BWAPI::TilePosition previousStartTile;
00236         // first tile to increment from
00237         // getting the current tile
00238         BWAPI::TilePosition startTile;
00239         // first good buildable tile found
00240         BWAPI::TilePosition newStartTile;
00241         // first tile to check for buildability
00242         BWAPI::TilePosition currentTile;
00243         // used in case no new start tiles found
00244         BWAPI::TilePosition unbuildableStartTile;
00245         // keep track of side lengths to know
00246         // when to change sides and direction
00247         vector<int> currentSideLengths;
00248         // derived from found buildable tiles
00249         vector<int> newSideLengths;
00250         // instead of individual side lengths
00251         // each accumulates from last side
00252         // derived from currentSideLengths
00253         vector<int> whenToChangeSideLengths;
00254         // total # of tiles (for all sides)
00255         int currentTileTotalCount;
00256         int newTileTotalCount;
00257         // current side we are on
00258         int currentSide;
00259         // number of new build tiles for this side
00260         int newSideLength;
00261         EnhancedUI * eui = new EnhancedUI(); 
00262         BWTA::Polygon poly = regionSides.first->getPolygon(); 
00263 
00264         // old comment:
00265         // sides are added from left to bottom in constructor
00266         // check tiles diagonally from end tiles, and from corner tiles
00267         // next level or radius of search is based upon the side orientation
00268         // if there are 2 sides, there is a corner tile adjoinig them (shared)
00269         // search in a radial pattern sweeping clockwise
00270         // stop sweeping if tile is unbuildable or a supply depot build tile is found
00271         // correction:  there is a case where the chokepoint is on a ramp, in which
00272         // case the entire first area may not be buildable, this makes things a bit
00273         // more complicated in knowing what is the set of tiles that should be considered
00274         // each round, if none are found to be buildable, then your set is 0, so if
00275         // none are found to be buildable, then you should just expand the set normally
00276         // as if they were all found to be buildable in hopes of the next round finding
00277         // at least one buildable tile (use unbuildableTilesForRound)
00278 
00279         numSides = (int) regionSides.second.size();
00280         //numCorners = numSides - 1;
00281 
00282         assert(numSides);
00283 
00284         // left start tile, -x, +y
00285         // left next tile x=0, -y (move up)
00286         // top start tile -x, -y
00287         // top next tile +x, y=0 (move right)
00288         // right start tile +x, -y
00289         // right next tile x=0, +y (move down)
00290         // bottom start tile +x, +y
00291         // bottom next tile -x, y=0 (move left)
00292 
00293         // default is unset
00294         xDir = yDir = xStartDir = yStartDir = 0;
00295         newTileTotalCount = 0;
00296 
00297         // sort through the sides
00298         for (int m = 0; m < numSides; ++m) {
00299                 vector<BWAPI::TilePosition> sideTiles;
00300                 sideTiles = regionSides.second[m].getTilePositions();
00301 
00302                 // lengths of sides
00303                 if (m == 0) {
00304                         newSideLengths.push_back((int)sideTiles.size());
00305                         newTileTotalCount += (int)sideTiles.size();
00306                 }
00307                 // next side length is reduced since it shares a tile
00308                 // with the previous side
00309                 else {
00310                         newSideLengths.push_back((int)sideTiles.size() - 1);
00311                         newTileTotalCount += (int)sideTiles.size() - 1;
00312                 }
00313                 orientation = regionSides.second[m].getOrientation();
00314 
00315                 // only need the new start tile from the first side
00316                 if (m > 0) {
00317                         continue;
00318                 }
00319 
00320                 // establish the new start tile, and the directions
00321                 if (orientation == EnhancedSide::left) {
00322                         // left start tile, -x, +y
00323                         // left next tile x=0, -y (move up)
00324                         xStartDir = -1;
00325                         yStartDir = +1;
00326                         xDir = 0;
00327                         yDir = -1;
00328                         // reverse
00329                         newStartTile = sideTiles.back();
00330                         horizontalSide = false;
00331                 }
00332                 else if (orientation == EnhancedSide::top) {
00333                         // top start tile -x, -y
00334                         // top next tile +x, y=0 (move right)
00335                         xStartDir = -1;
00336                         yStartDir = -1;
00337                         xDir = +1;
00338                         yDir = 0;
00339                         newStartTile = sideTiles.front();
00340 
00341                         horizontalSide = true;
00342 
00343                 }
00344                 else if (orientation == EnhancedSide::right) {
00345                         // right start tile +x, -y
00346                         // right next tile x=0, +y (move down)
00347                         xStartDir = +1;
00348                         yStartDir = -1;
00349                         xDir = 0;
00350                         yDir = +1;
00351                         newStartTile = sideTiles.front();
00352                         horizontalSide = false;
00353 
00354                 }
00355                 else if (orientation == EnhancedSide::bottom) {
00356                         // bottom start tile +x, +y
00357                         // bottom next tile -x, y=0 (move left)
00358                         xStartDir = +1;
00359                         yStartDir = +1;
00360                         xDir = -1;
00361                         yDir = 0;
00362                         newStartTile = sideTiles.back();
00363                         //reverse = true;
00364 
00365                         horizontalSide = true;
00366                 }
00367         } // end search sides
00368 
00369 
00370         // may use this later to check initial side tiles for buildability
00371         // but not exactly this way, don't really care about the order...
00372         //      if (reverse) {
00373 
00374         //              for (int n = (int) sideTiles.size() - 1; n >= 0; --n) {
00375         //                      if ( m > 0 && n == (int) sideTiles.size() - 1) {
00376         //                              corners.push_back(sideTiles[n]);
00377         //                              // and skip start of 2nd side (don't add twice since shared)
00378         //                      }
00379         //                      else {
00380         //                              currentTilesToSearchFrom.push_back(sideTiles[n]);
00381         //                      }
00382         //              }
00383         //      }
00384         //      else {
00385 
00386         //              for (int n = 0; n < (int) sideTiles.size(); ++n) {
00387 
00388         //                      if (m > 0 && n == 0) {
00389         //                              corners.push_back(sideTiles[n]);
00390         //                              // and skip start of 2nd side (don't add twice since shared)
00391         //                      }
00392         //                      else {
00393         //                              currentTilesToSearchFrom.push_back(sideTiles[n]);
00394         //                      }
00395         //              }
00396         //      }
00397         //}
00398 
00399         // init vars
00400         foundBuildTile = false;
00401         radiusLevel = 0;
00402         newSideLength = 0;
00403 
00404         // set first sides direction
00405         sideDirection;
00406         sideDirection.clear();
00407         sideDirection.push_back((int)horizontalSide);
00408         sideDirection.push_back(xDir);
00409         sideDirection.push_back(yDir);
00410         directionOfSides.push_back(sideDirection);
00411 
00412         // now search until a build tile is found
00413 
00414         while (!foundBuildTile) {
00415 
00416                 // reset before each round
00417                 whenToChangeSideLengths.clear();
00418                 currentSide = 0;
00419                 // this also gets reset when the side changes
00420                 newSideLength = 0;
00421                 lastTileBuildable = false;
00422                 // side direction (1 && for warning suppression)
00423                 horizontalSide = (1 && directionOfSides[currentSide][0]);
00424                 xDir = directionOfSides[currentSide][1];
00425                 yDir = directionOfSides[currentSide][2];
00426 
00427                 // not used currently, but maybe later
00428                 if (radiusLevel > 0) {
00429                         previousStartTile = startTile;
00430                 }
00431 
00432                 // if no buildable tiles are found in the round
00433                 // continue as if all were found to be buildable
00434                 if (radiusLevel > 0 && !foundStartTile) {
00435                         startTile = unbuildableStartTile;
00436                         currentTile = unbuildableStartTile;
00437                         currentTileTotalCount += 2 * (int)currentSideLengths.size();
00438                         int tileCount = 0;
00439                         for (int n = 0; n < (int) currentSideLengths.size(); ++n) {
00440                                 // same # of sides as before, just longer, so no clear
00441                                 currentSideLengths[n] += 2;
00442                                 tileCount += currentSideLengths[n];
00443                                 whenToChangeSideLengths.push_back(tileCount - 1);
00444                         }
00445                 }
00446                 else {
00447                         startTile = newStartTile;
00448                         // will be incremented on x and y
00449                         currentTile = startTile;
00450                         // what to grow out by
00451                         currentTileTotalCount = newTileTotalCount + 2 * (int)newSideLengths.size();
00452                         currentSideLengths.clear();
00453                         int tileCount = 0; 
00454                         for (int n = 0; n < (int) newSideLengths.size(); ++n) {
00455                                 currentSideLengths.push_back(newSideLengths[n] + 2);
00456                                 tileCount += newSideLengths[n] + 2;
00457                                 whenToChangeSideLengths.push_back(tileCount - 1);
00458                         }
00459 
00460                 }
00461                 // reset round 
00462                 // newSideLengths is set at the end of each round
00463                 newSideLengths.clear();
00464                 foundStartTile = false;
00465                 newTileTotalCount = 0;
00466 
00467 
00468                 // increment
00469                 currentTile.x() += xStartDir;
00470                 currentTile.y() += yStartDir;
00471 
00472                 // start this round
00473                 for (int m = 0; m < currentTileTotalCount; ++m) {
00474 
00475                         // only used if no start tile is found in this round
00476                         if (m == 0) {
00477                                 unbuildableStartTile = currentTile;
00478                         }               
00479 
00480                         if (BWAPI::Broodwar->isBuildable(currentTile, true) && 
00481                                 isPositionInPolygon(eui->getTilePositionCenter(currentTile), poly)) {
00482                                         buildableTiles.push_back(currentTile);
00483                                         newSideLength++;
00484                                         newTileTotalCount++;
00485                                         lastTileBuildable = true; // per round
00486                                         if (!foundStartTile) {
00487                                                 newStartTile = currentTile;
00488                                                 foundStartTile = true;
00489 
00490                                                 // see if we are on a different side now, 
00491                                                 // if so, need to change xStartDir and yStartDir
00492                                                 // used saved directions, but also remove any
00493                                                 // saved directions for sides that got eliminated
00494                                                 if (currentSide > 0) {
00495                                                         // shift all to the left by 1
00496                                                         for (int n = 0; n < currentSide; ++n) {
00497                                                                 // from horizontal to vertical
00498                                                                 if (directionOfSides[n][0]) {
00499                                                                         xStartDir = xStartDir * -1;
00500                                                                 }
00501                                                                 else {
00502                                                                         yStartDir = yStartDir * -1;
00503                                                                 }
00504                                                                 // pop front
00505                                                                 directionOfSides[n] = directionOfSides[n+1];
00506                                                         }
00507                                                         // pop back, so no doubles
00508                                                         directionOfSides.pop_back();
00509                                                 }
00510                                         }
00511 
00512                                         if (BWAPI::Broodwar->canBuildHere(NULL, currentTile, BWAPI::UnitTypes::Terran_Supply_Depot, false)) {
00513                                                 foundBuildTile = true; // yay!
00514                                                 buildTile = currentTile;
00515                                                 break;
00516                                         }
00517                         }
00518                         else if (lastTileBuildable) {
00519                                 // move on to next round since this tile
00520                                 // is not buildable and the last was
00521                                 //
00522                                 // Note: there can be the case where you
00523                                 // get a few buildable, then not buildable
00524                                 // then buildable again, but for now we want
00525                                 // to limit our search, unless this proves to 
00526                                 // be not so good, if then, the newSideLength
00527                                 // needs to be changed as it only counts for
00528                                 // buildable tiles
00529                                 break;
00530                         }
00531 
00532                         // check for change in direction for next side
00533                         // if so push back size for newSideLengths
00534                         if (m == (whenToChangeSideLengths[currentSide]) && 
00535                                 m != (currentTileTotalCount - 1)) { // skip on last tile
00536 
00537                                         newSideLengths.push_back(newSideLength);
00538                                         currentSide++;
00539                                         // reset for next side
00540                                         newSideLength = 0;
00541 
00542                                         // change direction based upon horizontality
00543                                         // how does this change per round?
00544                                         // what if the first side gets eliminated, that would
00545                                         // also change xStartDir and yStartDir for the start tile
00546                                         // find out if the start tile happens on the next side
00547                                         if (horizontalSide) {
00548                                                 yDir = xDir;
00549                                                 xDir = 0;
00550                                                 // switch
00551                                                 horizontalSide = false;
00552                                         }
00553                                         // vertical side
00554                                         else {
00555                                                 // opposite
00556                                                 xDir = yDir * -1;
00557                                                 yDir = 0;
00558                                                 // switch
00559                                                 horizontalSide = true;
00560                                         }
00561                                         // save direction for side on first round
00562                                         // 1st side already saved, 2nd side gets added now and then so on
00563                                         // needs to happen after the next sides direction is derived
00564                                         if (radiusLevel == 0) {
00565                                                 sideDirection;
00566                                                 sideDirection.clear();
00567                                                 sideDirection.push_back((int)horizontalSide);
00568                                                 sideDirection.push_back(xDir);
00569                                                 sideDirection.push_back(yDir);
00570                                                 directionOfSides.push_back(sideDirection);
00571                                         }
00572                         }
00573 
00574                         // increment direction
00575                         currentTile.x() += xDir;
00576                         currentTile.y() += yDir;
00577 
00578                 } // end round or radius level
00579 
00580                 // now at the end of last side, either by
00581                 // last tile or no more buildable tiles
00582                 newSideLengths.push_back(newSideLength);
00583 
00584                 // increment after each round
00585                 radiusLevel++;
00586 
00587         } // end while()
00588 
00589         // save data
00590 
00591         if (regionSides.first == regionABuildableTiles.first) {
00592                 regionABuildableTiles.second = buildableTiles;
00593                 regionABuildTile.second = buildTile;
00594         }
00595         else {
00596                 regionBBuildableTiles.second = buildableTiles;
00597                 regionBBuildTile.second = buildTile;
00598         }
00599 
00600         // clean up
00601         delete(eui);
00602 
00603         return;
00604 
00605 } // end func()
00606 
00607 
00608 /*
00609 * first position must be less then the second, ie always search down or right
00610 * does not check the corner points, only the inside points
00611 */
00612 bool EnhancedChokepoint::isSideInRegion(pair<BWAPI::Position, BWAPI::Position> endPoints, BWTA::Region * region)
00613 {
00614         BWAPI::Position pos;
00615         BWTA::Polygon poly;
00616 
00617         // only want sides longer than a tile length
00618         // that way if the bounding box is a single row
00619         // of tiles, one long side should be in one region
00620         // the other long side should be in the other region,
00621         // we don't care about the 2 short, 1 tile length sides
00622         // these should be covered anyways when you get the tiles
00623         // for the long side, it's still the same tile
00624         //
00625         // fine / coarse grain size, 32 = 1 tile length
00626         // start + 32 = start of next tile 
00627         const int grainLengthForSearch = 32;
00628 
00629         assert(region);
00630 
00631         poly = region->getPolygon();
00632 
00633         if (endPoints.first.x() == endPoints.second.x()) {
00634                 /* only search down */
00635                 assert(endPoints.first.y() <= endPoints.second.y());
00636                 /* search along y, x is constant */
00637                 pos = BWAPI::Position(endPoints.first.x(), endPoints.first.y() + grainLengthForSearch);
00638 
00639                 while (pos.y() < endPoints.second.y()) {
00640                         // BWTA isInside() is broken, use ours
00641                         //              if (poly.isInside(pos)) {
00642                         if (isPositionInPolygon(pos, poly)) {
00643                                 return true;
00644                         }
00645                         pos.y() += grainLengthForSearch;
00646                 }
00647         }
00648         else {
00649                 /* only search right */
00650                 assert(endPoints.first.x() <= endPoints.second.x());
00651                 /* search along x, y is constant */
00652                 pos = BWAPI::Position(endPoints.first.x() + grainLengthForSearch, endPoints.first.y());
00653 
00654                 while (pos.x() < endPoints.second.x()) {
00655                         // BWTA isInside() is broken, use ours
00656                         //if (poly.isInside(pos)) {
00657                         if (isPositionInPolygon(pos, poly)) {
00658                                 return true;
00659                         }
00660                         pos.x() += grainLengthForSearch;
00661                 }
00662         }
00663         return false;
00664 }
00665 vector<EnhancedSide> & EnhancedChokepoint::getBoundingBoxSidesForRegion(BWTA::Region * region)
00666 {
00667 
00668         assert(region);
00669 
00670         if (region == regionASides.first) {
00671                 return regionASides.second;
00672         }
00673 
00674         return regionBSides.second;
00675 }
00676 
00677 BWAPI::TilePosition EnhancedChokepoint::getBuildTile(BWTA::Region * region)
00678 {
00679         assert(region);
00680         if (region == regionABuildTile.first) {
00681                 return regionABuildTile.second;
00682         }
00683         return regionBBuildTile.second;
00684 }
00685 void EnhancedChokepoint::drawBoundingBoxSidesForRegion(BWTA::Region * region, BWAPI::Color color)
00686 {
00687         assert(region);
00688 
00689         if (region == regionASides.first) {
00690                 for (int m = 0; m < (int) regionASides.second.size(); ++m) {
00691                         regionASides.second[m].drawSide(color);
00692                 }
00693         }
00694         else if (region == regionBSides.first) {
00695                 for (int m = 0; m < (int) regionBSides.second.size(); ++m) {
00696                         regionBSides.second[m].drawSide(color);
00697                 }
00698         }
00699 }
00700 /* draws tile positions for the sides, and center */
00701 void EnhancedChokepoint::drawTilePositions() 
00702 {
00703         EnhancedUI * eui = new EnhancedUI();
00704         BWAPI::Color color = BWAPI::Colors::Purple;
00705         eui->drawTilePosition(this->tPosSides.first, color);
00706         eui->drawTilePosition(this->tPosSides.second, color);
00707         /* draw this last and in a different color */
00708         eui->drawTilePosition(this->tPosCenter, BWAPI::Colors::Yellow);
00709         delete eui;
00710 }
00711 
00712 void EnhancedChokepoint::drawBoundingBox(void)
00713 {
00714         BWAPI::Broodwar->drawBoxMap(xLeft, yTop, xRight, yBottom, BWAPI::Colors::White, false);
00715 }
00716 
00717 void EnhancedChokepoint::drawBuildableTilesForRegion(BWTA::Region * region, BWAPI::Color color)
00718 {
00719         assert(region);
00720 
00721         EnhancedUI * eui = new EnhancedUI();
00722         if (region == regionABuildableTiles.first) {
00723                 for (int m = 0; m < (int)regionABuildableTiles.second.size(); ++m) {
00724                         eui->drawTilePosition(regionABuildableTiles.second[m], color);
00725                 }
00726 
00727         }
00728         else {
00729                 for (int m = 0; m < (int)regionBBuildableTiles.second.size(); ++m) {
00730                         eui->drawTilePosition(regionBBuildableTiles.second[m], color);
00731                 }
00732         }
00733         delete eui;
00734 }
00735 void EnhancedChokepoint::drawBuildableSupplyDepotForRegion(BWTA::Region * region, 
00736                                                                                                                    BWAPI::Color color)
00737 {
00738         assert(region);
00739 
00740         EnhancedUI * eui = new EnhancedUI();
00741         const BWAPI::UnitType & depot = BWAPI::UnitTypes::Terran_Supply_Depot;
00742 
00743         if (region == regionABuildTile.first) {
00744 
00745                 //eui->drawTilePosition(regionABuildTile.second, color);
00746                 eui->drawBoxAtTilePositionToSize(regionABuildTile.second, depot.tileWidth(), 
00747                         depot.tileHeight(), color);
00748         }
00749         else {
00750                 //eui->drawTilePosition(regionBBuildTile.second, color);
00751                 eui->drawBoxAtTilePositionToSize(regionBBuildTile.second, depot.tileWidth(), 
00752                         depot.tileHeight(), color);
00753         }
00754         delete eui;
00755 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines