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