BWAPI
|
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 }