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); }
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; }
/* 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; } } } } } }
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; }
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; }
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; }
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; }
int operator()(TilePosition position, TilePosition target) { int h = 0; for each(Unit enemy in mEnemies) { h += mMmaxHValue - (int)position.getDistance(enemy->getTilePosition()); }
bool Squad::isCloseTo(TilePosition mGoal) { double dist = mGoal.getDistance(goal); if (dist <= 3) { return true; } return false; }
int MapDataReader::getDistance(TilePosition t1, TilePosition t2) { for (int i = 0; i < (int)data.size(); i++) { if (data.at(i).matches(t1, t2)) { return data.at(i).dist; } } int dist = (int)(t1.getDistance(t2)); return dist; }
TilePosition Commander::getClosestEnemyBuilding(TilePosition start) { Unit* closestBuilding = NULL; SpottedObject* closestObj = NULL; double bestDist = -1; for(set<Unit*>::const_iterator i=Broodwar->enemy()->getUnits().begin();i!=Broodwar->enemy()->getUnits().end();i++) { if ((*i)->getType().isBuilding()) { //V2 double cDist = start.getDistance((*i)->getTilePosition()); //V1 - TODO: Better, but too damn slow //vector<TilePosition> path = BWTA::getShortestPath(start, (*i)->getTilePosition()); //double cDist = (double)path.size(); if (!ExplorationManager::canReach(start, (*i)->getTilePosition())) { cDist = -1; } if (bestDist < 0 || cDist < bestDist) { bestDist = cDist; closestBuilding = (*i); } } } if (closestBuilding != NULL) { //Broodwar->printf("[TSC]: Closest enemy building is %s", closestBuilding->getType().getName().c_str()); return closestBuilding->getTilePosition(); } else if (ExplorationManager::getInstance()->isActive()) { bestDist = -1; vector<SpottedObject*> units = ExplorationManager::getInstance()->getSpottedBuildings(); for (int i = 0; i < (int)units.size(); i++) { SpottedObject* obj = units.at(i); if (obj->getType().isBuilding() && obj->isActive()) { double cDist = obj->getDistance(start); if (bestDist < 0 || cDist < bestDist) { bestDist = cDist; closestObj = obj; } } } //Broodwar->printf("[TSC]: using ExpManager. Closest is %s", closestObj.getType().getName().c_str()); } else { //Broodwar->printf("[TSC]: No enemy building found"); return TilePosition(-1, -1); } return closestObj->getTilePosition(); }
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; } }
Unit BuildingPlacer::hasMineralNear(TilePosition pos) { for (auto &u : Broodwar->getMinerals()) { if (u->exists() && u->getResources() > 0) { double dist = pos.getDistance(u->getTilePosition()); if (dist <= 10) { return u; } } } return NULL; }
TilePosition Squad::getClosestStartLocation(TilePosition pos) { TilePosition sloc = pos; double bestDist = 10000; for(set<BaseLocation*>::const_iterator i=getStartLocations().begin();i!=getStartLocations().end();i++) { TilePosition basePos = (*i)->getTilePosition(); double dist = pos.getDistance(basePos); if (dist < bestDist) { bestDist = dist; sloc = basePos; } } return sloc; }
int BuildPlanner::mineralsNearby(TilePosition center) { int mineralCnt = 0; for(set<Unit*>::iterator m = Broodwar->getMinerals().begin(); m != Broodwar->getMinerals().end(); m++) { if ((*m)->exists()) { double dist = center.getDistance((*m)->getTilePosition()); if (dist <= 10) { mineralCnt += (*m)->getResources(); } } } return mineralCnt; }
int Constructor::mineralsNearby(TilePosition center) { int mineralCnt = 0; for (auto &u : Broodwar->getMinerals()) { if (u->exists()) { double dist = center.getDistance(u->getTilePosition()); if (dist <= 10) { mineralCnt += u->getResources(); } } } return mineralCnt; }
int ExplorationManager::spottedBuildingsWithinRange(TilePosition pos, int range) { cleanup(); int eCnt = 0; for (int i = 0; i < (int)spottedBuildings.size(); i++) { if (spottedBuildings.at(i)->isActive()) { if (pos.getDistance(spottedBuildings.at(i)->getTilePosition()) <= range) { eCnt++; } } } return eCnt; }
bool Commander::chokePointFortified(TilePosition center) { vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents(); for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->isAlive()) { if (agents.at(i)->isOfType(UnitTypes::Terran_Bunker) || agents.at(i)->isOfType(UnitTypes::Protoss_Photon_Cannon) || agents.at(i)->isOfType(UnitTypes::Zerg_Sunken_Colony) || agents.at(i)->isOfType(UnitTypes::Zerg_Creep_Colony) || agents.at(i)->isOfType(UnitTypes::Zerg_Spore_Colony)) { double dist = center.getDistance(agents.at(i)->getUnit()->getTilePosition()); if (dist <= 20) { return true; } } } } return false; }
TilePosition ExplorationManager::getClosestSpottedBuilding(TilePosition start) { cleanup(); TilePosition pos = TilePosition(-1, -1); double bestDist = 100000; for (int i = 0; i < (int)spottedBuildings.size(); i++) { if (spottedBuildings.at(i)->isActive()) { double cDist = start.getDistance(spottedBuildings.at(i)->getTilePosition()); if (cDist < bestDist) { bestDist = cDist; pos = spottedBuildings.at(i)->getTilePosition(); } } } return pos; }
TilePosition BuildingPlacer::findRefineryBuildSpot(UnitType toBuild, TilePosition start) { TilePosition buildSpot = findClosestGasWithoutRefinery(toBuild, start); if (buildSpot.x >= 0) { BaseAgent* base = AgentManager::getInstance()->getClosestBase(buildSpot); if (base == NULL) { Broodwar << "No base found" << endl; return TilePosition(-1,-1); } else { double dist = buildSpot.getDistance(base->getUnit()->getTilePosition()); if (dist >= 14) { return TilePosition(-1,-1); } } } return buildSpot; }
TilePosition AgentManager::getClosestDetector(TilePosition startPos) { TilePosition pos = TilePosition(-1, -1); double bestDist = 10000; for (auto &a : agents) { if (a->isAlive()) { if (a->getUnitType().isDetector() && a->getUnitType().isBuilding()) { double cDist = startPos.getDistance(a->getUnit()->getTilePosition()); if (cDist < bestDist) { bestDist = cDist; pos = a->getUnit()->getTilePosition(); } } } } return pos; }
TilePosition CoverMap::findRefineryBuildSpot(UnitType toBuild, TilePosition start) { TilePosition buildSpot = findClosestGasWithoutRefinery(toBuild, start); if (buildSpot.x() >= 0) { BaseAgent* base = AgentManager::getInstance()->getClosestBase(buildSpot); if (base == NULL) { Broodwar->printf("No base found"); return TilePosition(-1,-1); } else { double dist = buildSpot.getDistance(base->getUnit()->getTilePosition()); if (dist >= 13) { Broodwar->printf("Base too far away %d", (int)dist); return TilePosition(-1,-1); } } } return buildSpot; }
TilePosition AgentManager::getClosestDetector(TilePosition startPos) { TilePosition pos = TilePosition(-1, -1); double bestDist = 10000; for (int i = 0; i < (int)agents.size(); i++) { BaseAgent* agent = agents.at(i); if (agent->isAlive()) { if (agent->getUnitType().isDetector() && agent->getUnitType().isBuilding()) { double cDist = startPos.getDistance(agent->getUnit()->getTilePosition()); if (cDist < bestDist) { bestDist = cDist; pos = agent->getUnit()->getTilePosition(); } } } } return pos; }
TilePosition Commander::findDefensePos(Chokepoint* choke) { TilePosition defPos = TilePosition(choke->getCenter()); TilePosition chokePos = defPos; double size = choke->getWidth(); if (size <= 32 * 3) { //Very narrow chokepoint, dont crowd it double bestDist = 10000; TilePosition basePos = Broodwar->self()->getStartLocation(); int maxD = 3; int minD = 2; //We found a chokepoint. Now we need to find a good place to defend it. for (int cX = chokePos.x() - maxD; cX <= chokePos.x() + maxD; cX++) { for (int cY = chokePos.y() - maxD; cY <= chokePos.y() + maxD; cY++) { TilePosition cPos = TilePosition(cX, cY); if (ExplorationManager::canReach(basePos, cPos)) { double chokeDist = chokePos.getDistance(cPos); double baseDist = basePos.getDistance(cPos); if (chokeDist >= minD && chokeDist <= maxD) { if (baseDist < bestDist) { bestDist = baseDist; defPos = cPos; } } } } } } //Make defenders crowd around defensive structures. if (Broodwar->self()->getRace().getID() == Races::Zerg.getID()) { UnitType defType; if (Constructor::isZerg()) defType = UnitTypes::Zerg_Sunken_Colony; if (Constructor::isProtoss()) defType = UnitTypes::Protoss_Photon_Cannon; if (Constructor::isTerran()) defType = UnitTypes::Terran_Bunker; BaseAgent* turret = AgentManager::getInstance()->getClosestAgent(defPos, defType); if (turret != NULL) { TilePosition tPos = turret->getUnit()->getTilePosition(); double dist = tPos.getDistance(defPos); if (dist <= 22) { defPos = tPos; } } } return defPos; }
TilePosition Squad::getCenter() { if (agents.size() == 1) { return agents.at(0)->getUnit()->getTilePosition(); } int cX = 0; int cY = 0; int cnt = 0; //Calculate sum (x,y) for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->isAlive()) { TilePosition unitPos = agents.at(i)->getUnit()->getTilePosition(); if (!unitPos.isValid()) { Broodwar->printf("Encountered invalid position, skipping"); continue; } cX += unitPos.x(); cY += unitPos.y(); cnt++; } } //Calculate average (x,y) if(cnt > 0) { cX = cX / cnt; cY = cY / cnt; } //To make sure the center is in a walkable tile, we need to //find the unit closest to center TilePosition c = TilePosition(cX, cY); TilePosition bestSpot = c; double bestDist = 10000; for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->isAlive()) { TilePosition unitPos = agents.at(i)->getUnit()->getTilePosition(); if (!unitPos.isValid()) continue; if ( (isAir() && agents.at(i)->getUnitType().isFlyer()) || (isGround() && !agents.at(i)->getUnitType().isFlyer())) { double dist = unitPos.getDistance(c); if (dist < bestDist) { bestDist = dist; bestSpot = unitPos; } } } } if (!bestSpot.isValid()) { Broodwar->printf("Invalid positions has distrupted the time-space continuum, expect the universe to implode."); } return bestSpot; }
TilePosition Commander::getClosestEnemyBuilding(TilePosition start) { Unit* closestBuilding = NULL; SpottedObject* closestObj = NULL; double bestDist = -1; for(set<Unit*>::const_iterator i=Broodwar->enemy()->getUnits().begin();i!=Broodwar->enemy()->getUnits().end();i++) { if ((*i)->getType().isBuilding()) { double cDist = start.getDistance((*i)->getTilePosition()); if (!ExplorationManager::canReach(start, (*i)->getTilePosition())) { //cDist = -1; } if (bestDist < 0 || cDist < bestDist) { bestDist = cDist; closestBuilding = (*i); } } } if (closestBuilding != NULL) { //Broodwar->printf("[TSC]: Closest enemy building is %s", closestBuilding->getType().getName().c_str()); return closestBuilding->getTilePosition(); } if (ExplorationManager::getInstance()->isActive()) { bestDist = -1; vector<SpottedObject*> units = ExplorationManager::getInstance()->getSpottedBuildings(); for (int i = 0; i < (int)units.size(); i++) { SpottedObject* obj = units.at(i); if (obj->getType().isBuilding() && obj->isActive()) { double cDist = obj->getDistance(start); if (bestDist < 0 || cDist < bestDist) { bestDist = cDist; closestObj = obj; } } } if (closestObj != NULL) { //Broodwar->printf("[TSC]: Closest enemy building is %s", closestBuilding->getType().getName().c_str()); return closestObj->getTilePosition(); } } //No building has been spotted. Move towards a starting point. for (int i = 0; i < (int)squads.size(); i++) { if (squads.at(i)->isOffensive() && squads.at(i)->getSize() > 0) { TilePosition nextArea = squads.at(i)->getNextStartLocation(); return nextArea; } } return TilePosition(-1,-1); }
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); }