bool Commander::isOccupied(BWTA::Region* region) { BWTA::Polygon p = region->getPolygon(); vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents(); for (int i = 0; i < (int)agents.size(); i++) { BaseAgent* agent = agents.at(i); if (agent->isAlive() && agent->getUnitType().isResourceDepot()) { BWTA::Region* aRegion = getRegion(agents.at(i)->getUnit()->getTilePosition()); Position c1 = region->getCenter(); Position c2 = aRegion->getCenter(); if (c2.x() == c1.x() && c2.y() == c1.y()) { return true; } } } //Check expansion site TilePosition expansionSite = ExplorationManager::getInstance()->getExpansionSite(); TilePosition center = TilePosition(region->getCenter()); if (expansionSite.x() >= 0) { double dist = expansionSite.getDistance(center); if (dist <= 15) { return true; } } return false; }
void InformationManager::onUnitDiscover( BWAPI::Unit* unit ) { // Sanity check if ( unit == NULL ) { return; } m_savedData[unit].m_exists = true; // If this is an enemy unit, try to infer build time and start location, and base location if ( BWAPI::Broodwar->self()->isEnemy( unit->getPlayer() ) ) { int time = BWAPI::Broodwar->getFrameCount(); BWAPI::UnitType type = unit->getType(); updateBuildTime( type, time - type.buildTime() ); if ( m_scoutedAnEnemyBase == false && unit->getType().isBuilding() ) { // We haven't scouted the enemy base yet, but this is a building BWTA::Region* r = BWTA::getRegion( unit->getTilePosition() ); if ( r->getBaseLocations().size() == 1 ) { // So the enemy probably spawned here. BWTA::BaseLocation* b = *( r->getBaseLocations().begin() ); m_enemyBases.insert( b ); m_scoutedAnEnemyBase = true; } } if ( unit->getType().isResourceDepot() ) { // This is a center, so we know its a base location BWTA::BaseLocation* b = BWTA::getNearestBaseLocation( unit->getTilePosition() ); m_enemyBases.insert( b ); m_enemyBaseCenters[b] = unit; m_scoutedAnEnemyBase = true; } } }
TilePosition ExplorationManager::getNextToExplore(Squad* squad) { TilePosition curPos = squad->getCenter(); TilePosition goal = squad->getGoal(); //Special case: No goal set if (goal.x() == -1 || goal.y() == -1) { BWTA::Region* startRegion = getRegion(curPos); goal = TilePosition(startRegion->getCenter()); return goal; } double dist = curPos.getDistance(goal); double acceptDist = 4; if (squad->isGround()) { acceptDist = 6; } if (dist <= acceptDist) { //Squad is close to goal //1. Set region to explored setExplored(goal); //2. Find new region to explore BWTA::Region* startRegion = getRegion(goal); BWTA::Region* bestRegion = startRegion; if (bestRegion != NULL) { int bestLastVisitFrame = getLastVisitFrame(bestRegion); if (!squad->isAir()) { //Ground explorers for(set<BWTA::Region*>::const_iterator i=startRegion->getReachableRegions().begin();i!=startRegion->getReachableRegions().end();i++) { int cLastVisitFrame = getLastVisitFrame((*i)); TilePosition c = TilePosition((*i)->getCenter()); if (cLastVisitFrame <= bestLastVisitFrame) { bestLastVisitFrame = cLastVisitFrame; bestRegion = (*i); } } } else { //Air explorers double bestDist = 100000; for(set<BWTA::Region*>::const_iterator i=getRegions().begin();i!=getRegions().end();i++) { int cLastVisitFrame = getLastVisitFrame((*i)); TilePosition c = TilePosition((*i)->getCenter()); double dist = c.getDistance(curPos); if (cLastVisitFrame < bestLastVisitFrame) { bestLastVisitFrame = cLastVisitFrame; bestRegion = (*i); bestDist = dist; } if (cLastVisitFrame == bestLastVisitFrame && dist < bestDist) { bestLastVisitFrame = cLastVisitFrame; bestRegion = (*i); bestDist = dist; } } } TilePosition newGoal = TilePosition(bestRegion->getCenter()); return newGoal; //Broodwar->printf("Explorer: new goal (%d,%d) I am at (%d,%d) agentGoal (%d,%d)", newGoal.x(), newGoal.y(), curPos.x(), curPos.y(), agent->getGoal().x(), agent->getGoal().y()); } } return TilePosition(-1, -1); }
void CombatCommander::updateScoutDefenseSquad() { if (_combatUnits.empty()) { return; } // if the current squad has units in it then we can ignore this Squad & scoutDefenseSquad = _squadData.getSquad("ScoutDefense"); // get the region that our base is located in BWTA::Region * myRegion = BWTA::getRegion(BWAPI::Broodwar->self()->getStartLocation()); if (!myRegion && myRegion->getCenter().isValid()) { return; } // get all of the enemy units in this region BWAPI::Unitset enemyUnitsInRegion; for (auto & unit : BWAPI::Broodwar->enemy()->getUnits()) { if (BWTA::getRegion(BWAPI::TilePosition(unit->getPosition())) == myRegion) { enemyUnitsInRegion.insert(unit); } } // if there's an enemy worker in our region then assign someone to chase him bool assignScoutDefender = enemyUnitsInRegion.size() == 1 && (*enemyUnitsInRegion.begin())->getType().isWorker(); // if our current squad is empty and we should assign a worker, do it if (scoutDefenseSquad.isEmpty() && assignScoutDefender) { // the enemy worker that is attacking us BWAPI::Unit enemyWorker = *enemyUnitsInRegion.begin(); // get our worker unit that is mining that is closest to it BWAPI::Unit workerDefender = findClosestWorkerToTarget(_combatUnits, enemyWorker); if (enemyWorker && workerDefender) { // grab it from the worker manager and put it in the squad if (_squadData.canAssignUnitToSquad(workerDefender, scoutDefenseSquad)) { WorkerManager::Instance().setCombatWorker(workerDefender); _squadData.assignUnitToSquad(workerDefender, scoutDefenseSquad); } } } // if our squad is not empty and we shouldn't have a worker chasing then take him out of the squad else if (!scoutDefenseSquad.isEmpty() && !assignScoutDefender) { for (auto & unit : scoutDefenseSquad.getUnits()) { unit->stop(); if (unit->getType().isWorker()) { WorkerManager::Instance().finishedWithWorker(unit); } } scoutDefenseSquad.clear(); } }
//ctx add BWAPI::TilePosition BuildingPlacer::getBuildLocationFarFromChokePoint(const Building & b, int buildDist, bool horizontalOnly, bool flag) const { SparCraft::Timer t; t.start(); BWAPI::TilePosition startTitlePos = BWAPI::Broodwar->self()->getStartLocation(); BWTA::Chokepoint *chokePoint = BWTA::getNearestChokepoint(startTitlePos); BWAPI::Position chokeCenterPosition = chokePoint->getCenter(); BWTA::Region *baseRegion = BWTA::getRegion(BWAPI::Broodwar->self()->getStartLocation()); BWTA::Polygon basePolygon = baseRegion->getPolygon(); BWAPI::Position farPosition = BWAPI::Position(0, 0); BWAPI::TilePosition resultPosition = BWAPI::TilePosition(0, 0); double dis = 0.0; for (int i = 0; i < (int)basePolygon.size(); i++) { BWAPI::Position point = basePolygon[i]; double ms1 = t.getElapsedTimeInMilliSec(); if (point.getDistance(chokeCenterPosition) > dis) { dis = point.getDistance(chokeCenterPosition); farPosition = point; } } const std::vector<BWAPI::TilePosition> & closestToBuilding = MapTools::Instance().getClosestTilesTo(BWAPI::Position(b.desiredPosition)); //get best solution dis = farPosition.getDistance(BWAPI::Position(startTitlePos)); if (flag == true) { for (size_t i = 0; i < closestToBuilding.size(); ++i) { double ms1 = t.getElapsedTimeInMilliSec(); if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis > farPosition.getDistance(BWAPI::Position(closestToBuilding[i]))) { resultPosition = closestToBuilding[i]; break; //return closestToBuilding[i]; } } } else { for (size_t i = 0; i < closestToBuilding.size(); ++i) { double ms1 = t.getElapsedTimeInMilliSec(); if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis < farPosition.getDistance(BWAPI::Position(closestToBuilding[i]))) { resultPosition = closestToBuilding[i]; break; //return closestToBuilding[i]; } } } if (!basePolygon.isInside(BWAPI::Position(resultPosition))) { resultPosition = getBuildLocationNear(b, buildDist, horizontalOnly); } return resultPosition; }
BWAPI::TilePosition BuildingPlacer::getBuildLocationNear(const Building & b, int buildDist, int timeLimitMS, bool inRegionPriority, bool horizontalOnly) const { struct SearchState{ int _length; int _j; bool _first; int _dx; int _dy; int _x; int _y; bool _timeOut; BWAPI::TilePosition _candidatePos; SearchState(int length, int j, bool first, int dx, int dy, int x, int y, bool timeOut = false, BWAPI::TilePosition candidatePos = BWAPI::TilePositions::None) : _length(length), _j(j), _first(first), _dx(dx), _dy(dy), _x(x), _y(y), _timeOut(timeOut), _candidatePos(candidatePos) {} SearchState() :_timeOut(false), _candidatePos(BWAPI::TilePositions::None) {} }; struct SearchParams{ Building _b; int _buildDist; bool _inRegionPriority; bool _horizontalOnly; SearchParams(const Building & b, int buildDist, bool inRegionPriority, bool horizontalOnly): _b(b), _buildDist(buildDist), _inRegionPriority(inRegionPriority), _horizontalOnly(horizontalOnly) {} SearchParams() {} bool operator==(const SearchParams& other) { return _b.type == other._b.type && _b.desiredPosition == other._b.desiredPosition&& _b.builderUnit == other._b.builderUnit&& _buildDist == other._buildDist&& _inRegionPriority == other._inRegionPriority&& _horizontalOnly == other._horizontalOnly; } }; if (timeLimitMS <= 0) { throw std::runtime_error("Building Placer not given any time: "+timeLimitMS); } static SearchState lastState; static SearchParams lastParams; SearchState state(1, 0, true, 0, 1, b.desiredPosition.x, b.desiredPosition.y); SearchParams params(b, buildDist, inRegionPriority, horizontalOnly); if (lastState._timeOut && lastParams == params) { state = lastState; //BWAPI::Broodwar->printf("Building Placer for building %s resuming... %d",b.type.getName().c_str(),state._length); //Logger::LogAppendToFile(UAB_LOGFILE, "Building Placer for building %s resuming... %d\n", b.type.getName().c_str(), state._length); } SparCraft::Timer t; t.start(); // my starting region //BWTA::Region * myRegion = BWTA::getRegion(BWTA::getStartLocation(BWAPI::Broodwar->self())->getTilePosition()); BWTA::Region * myRegion = BWTA::getRegion(b.desiredPosition); //get max spiral size int maxDist = 0; for (auto point : myRegion->getPolygon()) { int radius = std::ceil((BWAPI::TilePosition(point) - b.desiredPosition).getLength()); if (radius > maxDist) { maxDist = radius; } } while (state._length < maxDist || (state._length <BWAPI::Broodwar->mapWidth() && state._candidatePos == BWAPI::TilePositions::None)) //We'll ride the spiral to the end { if (t.getElapsedTimeInMilliSec() > timeLimitMS) { if (Options::Debug::DRAW_UALBERTABOT_DEBUG && !state._timeOut) { //BWAPI::Broodwar->printf("Building Placer Timed Out at %d ms on building %s", timeLimitMS, b.type.getName().c_str()); //Logger::LogAppendToFile(UAB_LOGFILE, "Building Placer Timed Out at %d ms on building %s\n", timeLimitMS, b.type.getName().c_str()); } lastState = state; lastState._timeOut = true; lastParams = params; throw std::runtime_error("Building Placer Timed Out. State saved for resuming later."); } //if we can build here, return this tile position if (state._x >= 0 && state._x < BWAPI::Broodwar->mapWidth() && state._y >= 0 && state._y < BWAPI::Broodwar->mapHeight()) { // can we build this building at this location bool canBuild = this->canBuildHereWithSpace(BWAPI::TilePosition(state._x, state._y), b, buildDist, horizontalOnly); if (canBuild) { // if this location has priority to be built within our own region if (inRegionPriority) { // the region the build tile is in BWTA::Region * tileRegion = BWTA::getRegion(BWAPI::TilePosition(state._x, state._y)); // is the proposed tile in our region? bool tileInRegion = (tileRegion == myRegion); // if the tile is in region and we can build it there if (tileInRegion) { if (Options::Debug::DRAW_UALBERTABOT_DEBUG) { //BWAPI::Broodwar->printf("Building Placer Took %lf ms", t.getElapsedTimeInMilliSec()); //BWAPI::Broodwar->printf("Building position found in region"); //Logger::LogAppendToFile(UAB_LOGFILE, "Building position found in region\n"); } // return that position lastState._timeOut = false; return BWAPI::TilePosition(state._x, state._y); } else if (state._candidatePos==BWAPI::TilePositions::None)//save an out of region position as candidate { if (Options::Debug::DRAW_UALBERTABOT_DEBUG) { //BWAPI::Broodwar->printf("Saving position found not in region"); //Logger::LogAppendToFile(UAB_LOGFILE, "Saving position found not in region\n"); } state._candidatePos = BWAPI::TilePosition(state._x, state._y); } } // otherwise priority is not set for this building else { if (Options::Debug::DRAW_UALBERTABOT_DEBUG) { //BWAPI::Broodwar->printf("Building Placer Took %lf ms", t.getElapsedTimeInMilliSec()); //BWAPI::Broodwar->printf("Building position found not in region"); //Logger::LogAppendToFile(UAB_LOGFILE, "Building position found not in region\n"); } lastState._timeOut = false; return BWAPI::TilePosition(state._x, state._y); } } } //otherwise, move to another position state._x = state._x + state._dx; state._y = state._y + state._dy; //count how many steps we take in this direction state._j++; if (state._j == state._length) //if we've reached the end, its time to turn { //reset step counter state._j = 0; //Spiral out. Keep going. if (!state._first) { state._length++; //increment step counter if needed } //first=true for every other turn so we spiral out at the right rate state._first = !state._first; //turn counter clockwise 90 degrees: if (state._dx == 0) { state._dx = state._dy; state._dy = 0; } else { state._dy = -state._dx; state._dx = 0; } } //Spiral out. Keep going. } lastState._timeOut = false; if (Options::Debug::DRAW_UALBERTABOT_DEBUG) { //BWAPI::Broodwar->printf("Rode spiral out. Building %s position: %d %d", b.type.getName().c_str(), state._candidatePos.x, state._candidatePos.y); //Logger::LogAppendToFile(UAB_LOGFILE, "Rode spiral out. Building %s position: %d %d\n", b.type.getName().c_str(), state._candidatePos.x, state._candidatePos.y); } return state._candidatePos; }
bool operator () (const BWAPI::TilePosition& position, const TileInformation& info) const { (void) info; return region->isReachable(BWTA::getRegion(position)); }