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; }
bool PFManager::moveToGoal(BaseAgent* agent, TilePosition checkpoint, TilePosition goal) { if (checkpoint.x() == -1 || goal.x() == -1) return false; Unit* unit = agent->getUnit(); if (unit->isStartingAttack() || unit->isAttacking()) { return false; } Position toReach = Position(checkpoint); double distToReach = toReach.getDistance(unit->getPosition()); int engageDist = unit->getType().groundWeapon().maxRange(); if (agent->isOfType(UnitTypes::Terran_Medic)) { engageDist = 6 * 32; } if (engageDist <= 64) { engageDist = 64; } if (distToReach <= engageDist) { if (unit->isMoving()) unit->stop(); return true; } //Move if (!unit->isMoving()) return unit->attack(toReach); else return true; }
TilePosition CoverMap::findExpansionSite() { UnitType baseType = Broodwar->self()->getRace().getCenter(); double bestDist = 100000; TilePosition bestPos = TilePosition(-1, -1); //Iterate through all base locations for(set<BWTA::BaseLocation*>::const_iterator i=BWTA::getBaseLocations().begin(); i!= BWTA::getBaseLocations().end(); i++) { TilePosition pos = (*i)->getTilePosition(); bool taken = false; //Check if own buildings are close vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents(); int noBases = 0; for (int i = 0; i < (int)agents.size(); i++) { BaseAgent* agent = agents.at(i); if (agent->isAlive() && agent->getUnitType().isResourceDepot()) { double dist = pos.getDistance(agent->getUnit()->getTilePosition()); if (dist <= 12) { noBases++; } } } if (BuildPlanner::isZerg()) { if (noBases >= 2) taken = true; } else { if (noBases >= 1) taken = true; } //Check if enemy buildings are close int eCnt = ExplorationManager::getInstance()->spottedBuildingsWithinRange(pos, 20); if (eCnt > 0) { taken = true; } //Not taken, calculate ground distance if (!taken) { if (ExplorationManager::canReach(Broodwar->self()->getStartLocation(), pos)) { double dist = mapData.getDistance(Broodwar->self()->getStartLocation(), pos); if (dist <= bestDist) { bestDist = dist; bestPos = pos; } } } } return bestPos; }
Unit BuildingPlacer::findClosestMineral(TilePosition workerPos) { Unit mineral = NULL; double bestDist = 10000; for(BaseLocation* base : getBaseLocations()) { TilePosition pos = base->getTilePosition(); double cDist = pos.getDistance(workerPos); if (cDist < bestDist) { //Find closest base BaseAgent* base = AgentManager::getInstance()->getClosestBase(pos); if (base != NULL) { double dist = pos.getDistance(base->getUnit()->getTilePosition()); if (dist <= 12) { //We have a base near this base location //Check if we have minerals available Unit cMineral = hasMineralNear(pos); if (cMineral != NULL) { mineral = cMineral; bestDist = cDist; } } } } } //We have no base with minerals, do nothing return mineral; }
void UnitClass::build(TilePosition target, BWAPI::UnitType type) { if(exists()) { const Position targetPosition(target.x()*32+type.tileWidth()*16, target.y()*32+type.tileHeight()*16); if(getDistance(type, targetPosition) > 48 || !MapHelper::isAllVisible(target, type)) { move(targetPosition, 0); return; } if(mUnit->getOrder() == BWAPI::Orders::PlaceBuilding) { if(mUnit->getBuildType() == type && mUnit->getOrderTargetPosition() == targetPosition) return; } if(mUnit->getLastCommand().getType() == BWAPI::UnitCommandTypes::Build && mUnit->getLastCommand().getUnitType() == type && mUnit->getLastCommand().getTargetTilePosition() == target) { if(mLastOrderExecuteTime >= BWAPI::Broodwar->getFrameCount()) return; } if(mUnit->build(target, type)) mLastOrderExecuteTime = BWAPI::Broodwar->getFrameCount() + BWAPI::Broodwar->getRemainingLatencyFrames(); else move(targetPosition, 0); } }
void Squad::removeMember(BaseAgent* agent) { //Step 1. Remove the agent instance for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->getUnitID() == agent->getUnitID()) { agents.at(i)->setSquadID(-1); agents.at(i)->assignToDefend(); agents.erase(agents.begin() + i); break; } } //Step 2. Update the setup list for (int i = 0; i < (int)setup.size(); i++) { if (setup.at(i).equals(agent->getUnitType())) { setup.at(i).current--; } } //Step 3. If Explorer, set destination as explored (to avoid being killed at the same //place over and over again). if (isExplorer()) { TilePosition goal = agent->getGoal(); if (goal.x() >= 0) { ExplorationManager::Instance().setExplored(goal); } } }
BWAPI::TilePosition getNextExpansionLocation(TilePosition currentExpo) { //remove the current expo from the list //loop through expos and find the nearest one std::set<BWTA::BaseLocation*> bases; for (auto &u : allBases) { //make sure we delete the current expansion if (u->getTilePosition() == currentExpo) { allBases.erase(u); } } BWTA::BaseLocation *ret = *allBases.begin(); int minDistance = currentExpo.getApproxDistance(ret->getTilePosition()); //make sure we dont accidently find current expansion for (auto &u : allBases) { int tempDistance = currentExpo.getApproxDistance(u->getTilePosition()); if (tempDistance < minDistance && tempDistance > 10) { //found a closer base minDistance = tempDistance; ret = u; } } return ret->getTilePosition(); }
bool Squad::isVisible(TilePosition pos) { if (!ExplorationManager::canReach(Broodwar->self()->getStartLocation(), pos)) { return true; } if (Broodwar->isVisible(pos)) { return true; } if (getCenter().getDistance(pos) <= 3) { return true; } for (int i = 0; i < (int)hasVisited.size(); i++) { TilePosition vPos = hasVisited.at(i); if (vPos.x() == pos.x() && vPos.y() == pos.y()) { return true; } } return false; }
Unit* CoverMap::findClosestMineral(TilePosition workerPos) { Unit* mineral = NULL; double bestDist = 10000; for(set<BWTA::BaseLocation*>::const_iterator i=BWTA::getBaseLocations().begin(); i!= BWTA::getBaseLocations().end(); i++) { TilePosition pos = (*i)->getTilePosition(); double cDist = pos.getDistance(workerPos); if (cDist < bestDist) { //Find closest base BaseAgent* base = AgentManager::getInstance()->getClosestBase(pos); double dist = pos.getDistance(base->getUnit()->getTilePosition()); if (dist <= 12) { //We have a base near this base location //Check if we have minerals available Unit* cMineral = hasMineralNear(pos); if (cMineral != NULL) { mineral = cMineral; bestDist = cDist; } } } } //We have no base with minerals, do nothing return mineral; }
/* if the mineral fields at our base are getting low then construct a new base */ void ProductionManager::checkMinerals() { if(!expansionQueued) { Unit* closestMineral = NULL; TilePosition home; //find main for(std::set<Unit*>::const_iterator i=Broodwar->self()->getUnits().begin();i!=Broodwar->self()->getUnits().end();i++) { if ((*i)->getType().isResourceDepot()) { home = (*i)->getTilePosition(); for(std::set<BWAPI::Unit*>::iterator m = Broodwar->getMinerals().begin(); m != Broodwar->getMinerals().end(); m++) { if (closestMineral==NULL || home.getDistance((*m)->getTilePosition()) < home.getDistance(closestMineral->getTilePosition())) closestMineral=*m; } if (closestMineral!=NULL) { if(closestMineral->getResources() < 150) { production.queueAsHighestPriority(MetaType(Broodwar->self()->getRace().getCenter()), true); expansionQueued = true; } } } } } }
TilePosition ExplorationManager::scanForVulnerableBase() { TilePosition spot = TilePosition(-1, -1); for (int i = 0; i < (int)spottedBuildings.size(); i++) { if (spottedBuildings.at(i)->isActive()) { SpottedObject* obj = spottedBuildings.at(i); if (obj->getType().isResourceDepot()) { if (!isDetectorCovering(obj->getTilePosition())) { //Broodwar->printf("Found probable vulnerable base at (%d,%d)", obj->getTilePosition().x(), obj->getTilePosition().y()); spot = obj->getTilePosition(); } } } } if (spot.x() < 0) { //Broodwar->printf("Scan: No vulnerable base found"); } return spot; }
void UnitClass::drawUnitTilePosition() { TilePosition tile = getTilePosition(); BWAPI::UnitType type = getType(); Player player = getPlayer(); BWAPI::Broodwar->drawBox(BWAPI::CoordinateType::Map, tile.x()*32, tile.y()*32, (tile.x()+type.tileWidth())*32, (tile.y()+type.tileHeight())*32, player->getColor()); }
bool CoverMap::positionFree(TilePosition pos) { if (cover_map[pos.x()][pos.y()] == BUILDABLE) { return true; } return false; }
void CoverMap::blockPosition(TilePosition buildSpot) { if (buildSpot.x() == -1) { //Error check return; } cover_map[buildSpot.x()][buildSpot.y()] = BLOCKED; }
bool PathObj::matches(TilePosition cStart, TilePosition cEnd) { //Check if end almost matches double dist = cEnd.getDistance(end); if (dist > 3) return false; //Check if start almost matches. dist = cStart.getDistance(start); if (dist > 5) return false; return true; }
void Squad::defend(TilePosition mGoal) { if (mGoal.x() == -1 || mGoal.y() == -1) return; if (currentState != STATE_DEFEND) { if (currentState == STATE_ASSIST && !isUnderAttack()) { currentState = STATE_DEFEND; } } setGoal(mGoal); }
void Commander::updateGoals() { TilePosition defSpot = findChokePoint(); if (defSpot.x() != -1) { for (int i = 0; i < (int)squads.size(); i++) { Squad* sq = squads.at(i); squads.at(i)->defend(defSpot); } } }
bool Squad::isThisGoal(TilePosition mGoal) { int xDiff = goal.x() - mGoal.x(); if (xDiff < 0) xDiff *= -1; int yDiff = goal.y() - mGoal.y(); if (yDiff < 0) yDiff *= -1; //Broodwar->printf("SQ %d: (%d,%d) = (%d,%d)", id, goal.x(), goal.y(), mGoal.x(), mGoal.y()); if (xDiff <= 2 && yDiff <= 2) { return true; } return false; }
TilePosition CoverMap::searchRefinerySpot() { for(int i = 0 ; i < w ; i++) { for (int j = 0; j < h; j++) { if (cover_map[i][j] == GAS) { TilePosition cPos = TilePosition(i,j); bool found = false; vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents(); for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->getUnitType().isRefinery()) { double dist = agents.at(i)->getUnit()->getTilePosition().getDistance(cPos); TilePosition uPos = agents.at(i)->getUnit()->getTilePosition(); if (dist <= 2) { found = true; break; } } } if (!found) { BaseAgent* agent = AgentManager::getInstance()->getClosestBase(cPos); if (agent != NULL) { TilePosition bPos = agent->getUnit()->getTilePosition(); double dist = bPos.getDistance(cPos); if (dist < 15) { if (ExplorationManager::canReach(bPos, cPos)) { return cPos; } } } } } } } return TilePosition(-1, -1); }
double Commander::getChokepointPrio(TilePosition center) { TilePosition ePos = ExplorationManager::getInstance()->getClosestSpottedBuilding(center); if (ePos.x() >= 0) { double dist = ePos.getDistance(center); return 1000 - dist; } else { double dist = Broodwar->self()->getStartLocation().getDistance(center); return dist; } }
bool CoverMap::canBuildAt(UnitType toBuild, TilePosition pos) { int maxW = w - toBuild.tileWidth() - 1; int maxH = h - toBuild.tileHeight() - 1; //Out of bounds check if (pos.x() >= 0 && pos.x() < maxW && pos.y() >= 0 && pos.y() < maxH) { if (canBuild(toBuild, pos)) { return true; } } return false; }
void BTHAIModule::onNukeDetect(BWAPI::Position target) { // TODO: React on this! Make all units move outside of the blast radius? // Notify the commander and let it make a decision? if (target != Positions::Unknown) { TilePosition t = TilePosition(target); Broodwar->printf("Nuclear Launch Detected at (%d,%d)",t.x(),t.y()); Commander::Instance().onNukeDetect(target); } else { Broodwar->printf("Nuclear Launch Detected"); } }
void BuildPlanner::expand(UnitType commandCenterUnit) { if (containsType(commandCenterUnit)) { return; } TilePosition pos = CoverMap::getInstance()->findExpansionSite(); if (pos.x() == -1) { //No expansion site found. return; } addBuildingFirst(commandCenterUnit); }
int operator()(TilePosition position, TilePosition target) { int h = 0; for each(Unit enemy in mEnemies) { h += mMmaxHValue - (int)position.getDistance(enemy->getTilePosition()); }
TilePosition Commander::findChokePoint() { //First, check the DefenseLocator //for a stored defense position. DefenseLocator* df = DefenseLocator::getInstance(); TilePosition storedPos = df->getBaseDefensePos(Broodwar->mapHash()); if (storedPos.x() != -1) return storedPos; double bestPrio = -1; Chokepoint* bestChoke = NULL; for(set<BWTA::Region*>::const_iterator i=getRegions().begin();i!=getRegions().end();i++) { if (isOccupied((*i))) { for(set<Chokepoint*>::const_iterator c=(*i)->getChokepoints().begin();c!=(*i)->getChokepoints().end();c++) { if (isEdgeChokepoint((*c))) { double cPrio = getChokepointPrio(TilePosition((*c)->getCenter())); if (cPrio > bestPrio) { bestPrio = cPrio; bestChoke = (*c); } } } } } TilePosition guardPos = Broodwar->self()->getStartLocation(); if (bestChoke != NULL) { guardPos = findDefensePos(bestChoke); //guardPos = TilePosition(bestChoke->getCenter()); //Pre-calculate path TilePosition b = ExplorationManager::getInstance()->getClosestSpottedBuilding(guardPos); if (b.x() >= 0) { Pathfinder::getInstance()->requestPath(guardPos, b); } } return guardPos; }
void ExplorationManager::setExpansionSite(TilePosition pos) { if (pos.x() >= 0) { siteSetFrame = Broodwar->getFrameCount(); expansionSite = pos; } }
TilePosition StructureAgent::getNextScanLocation() { TilePosition ePos = ExplorationManager::getInstance()->getClosestSpottedBuilding(Broodwar->self()->getStartLocation()); if (ePos.x() > -1) { //Already found enemy base return TilePosition(-1, -1); } for(set<BaseLocation*>::const_iterator i=getStartLocations().begin();i!=getStartLocations().end();i++) { TilePosition basePos = (*i)->getTilePosition(); bool needScan = true; //1. Check previous scans for (int i = 0; i < (int)hasScanned.size(); i++) { if (hasScanned.at(i).x() == basePos.x() && hasScanned.at(i).y() == basePos.y()) { needScan = false; } } //2. Check if we have this base vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents(); for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->isAlive()) { double dist = basePos.getDistance(agents.at(i)->getUnit()->getTilePosition()); if (dist <= 10) { needScan = false; break; } } } //3. Check if enemy units are near for(set<Unit*>::const_iterator j=Broodwar->enemy()->getUnits().begin();j!=Broodwar->enemy()->getUnits().end();j++) { if ((*j)->exists()) { double dist = basePos.getDistance((*j)->getTilePosition()); if (dist <= 10) { needScan = false; break; } } } if (needScan) { return basePos; } } return TilePosition(-1, -1); }
bool Commander::shallEngage() { TilePosition closeEnemy = getClosestEnemyBuilding(Broodwar->self()->getStartLocation()); if (closeEnemy.x() == -1) { //No enemy sighted. Dont launch attack. return false; } for (int i = 0; i < (int)squads.size(); i++) { if (squads.at(i)->isRequired() && !squads.at(i)->isActive()) { return false; } } return true; }
bool Squad::isCloseTo(TilePosition mGoal) { double dist = mGoal.getDistance(goal); if (dist <= 3) { return true; } return false; }
void ExplorationSquad::computeActions() { if (!active) { if (isFull()) { active = true; } return; } //First, remove dead agents for(int i = 0; i < (int)agents.size(); i++) { if(!agents.at(i)->isAlive()) { agents.erase(agents.begin() + i); i--; } } //All units dead, go back to inactive if ((int)agents.size() == 0) { active = false; return; } if (active) { if (activePriority != priority) { priority = activePriority; } TilePosition nGoal = ExplorationManager::Instance().getNextToExplore(this); if (nGoal.x() >= 0) { this->goal = nGoal; setMemberGoals(goal); } } }