void ExplorationManager::unitDestroyed(Unit* unit) { TilePosition uPos = unit->getTilePosition(); if (unit->getType().isBuilding()) { bool removed = false; for (int i = 0; i < (int)spottedBuildings.size(); i++) { TilePosition sPos = spottedBuildings.at(i)->getTilePosition(); if (uPos.x() == sPos.x() && uPos.y() == sPos.y()) { spottedBuildings.at(i)->setInactive(); removed = true; } } if (!removed) { //Broodwar->printf("[EM]: Building %s at (%d,%d) was not removed from EM!!!", unit->getType().getName().c_str(), uPos.x(), uPos.y()); } } else { for (int i = 0; i < (int)spottedUnits.size(); i++) { if (spottedUnits.at(i)->getUnitID() == unit->getID()) { spottedUnits.at(i)->setInactive(); //Broodwar->printf("[EM]: Remove %s at (%d,%d)", unit->getType().getName().c_str(), uPos.x(), uPos.y()); } } } }
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; }
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 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); } }
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); }
TilePosition CoverMap::findBuildSpot(UnitType toBuild, TilePosition start) { //Check start pos if (canBuildAt(toBuild, start)) return start; //Search outwards bool found = false; int cDiff = 1; TilePosition spot = TilePosition(-1, -1); while (!found) { //Top TilePosition s = TilePosition(start.x() - cDiff, start.y() - cDiff); TilePosition e = TilePosition(start.x() + cDiff, start.y() - cDiff); spot = findSpotAtSide(toBuild, s, e); if (spot.x() != -1 && spot.y() != -1) { found = true; break; } //Bottom s = TilePosition(start.x() - cDiff, start.y() + cDiff); e = TilePosition(start.x() + cDiff, start.y() + cDiff); spot = findSpotAtSide(toBuild, s, e); if (spot.x() != -1 && spot.y() != -1) { found = true; break; } //Left s = TilePosition(start.x() - cDiff, start.y() - cDiff); e = TilePosition(start.x() - cDiff, start.y() + cDiff); spot = findSpotAtSide(toBuild, s, e); if (spot.x() != -1 && spot.y() != -1) { found = true; break; } //Right s = TilePosition(start.x() + cDiff, start.y() - cDiff); e = TilePosition(start.x() + cDiff, start.y() + cDiff); spot = findSpotAtSide(toBuild, s, e); if (spot.x() != -1 && spot.y() != -1) { found = true; break; } cDiff++; if (cDiff > range) found = true; } return spot; }
bool CoverMap::positionFree(TilePosition pos) { if (cover_map[pos.x()][pos.y()] == BUILDABLE) { return true; } return false; }
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 AgentManager::unitsInArea(TilePosition pos, int tileWidth, int tileHeight, int unitID) { for (int i = 0; i < (int)agents.size(); i++) { if (agents.at(i)->isAlive()) { if (agents.at(i)->getUnit()->getID() != unitID) { TilePosition aPos = agents.at(i)->getUnit()->getTilePosition(); if (aPos.x() >= pos.x() && aPos.x() <= pos.x() + tileWidth && aPos.y() >= pos.y() && aPos.y() <= pos.y() + tileWidth) { return true; } } } } return false; }
bool ExplorationManager::canReach(TilePosition a, TilePosition b) { int w = Broodwar->mapWidth(); int h = Broodwar->mapHeight(); if (a.x() < 0 || a.x() >= w || a.y() < 0 || a.y() >= h) { return false; } if (b.x() < 0 || b.x() >= w || b.y() < 0 || b.y() >= h) { return false; } bool ok = true; ok = a.hasPath(b); return ok; }
void CoverMap::blockPosition(TilePosition buildSpot) { if (buildSpot.x() == -1) { //Error check return; } cover_map[buildSpot.x()][buildSpot.y()] = BLOCKED; }
TilePosition CoverMap::findSpotAtSide(UnitType toBuild, TilePosition start, TilePosition end) { int dX = end.x() - start.x(); if (dX != 0) dX = 1; int dY = end.y() - start.y(); if (dY != 0) dY = 1; TilePosition cPos = start; bool done = false; while (!done) { if (canBuildAt(toBuild, cPos)) return cPos; int cX = cPos.x() + dX; int cY = cPos.y() + dY; cPos = TilePosition(cX, cY); if (cPos.x() == end.x() && cPos.y() == end.y()) done = true; } return TilePosition(-1, -1); }
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); }
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; }
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"); } }
Corners CoverMap::getCorners(UnitType type, TilePosition center) { int x1 = center.x(); int y1 = center.y(); int x2 = x1 + type.tileWidth() - 1; int y2 = y1 + type.tileHeight() - 1; int margin = 1; if (type.canProduce()) { margin = 1; } if (BaseAgent::isOfType(type, UnitTypes::Terran_Supply_Depot)) { margin = 0; } if (BaseAgent::isOfType(type, UnitTypes::Protoss_Pylon)) { margin = 0; } x1 -= margin; x2 += margin; y1 -= margin; y2 += margin; //Special case: Terran Addon buildings //Add 2 extra spaces to the right to make space for the addons. if (BaseAgent::isOfType(type, UnitTypes::Terran_Factory) || BaseAgent::isOfType(type, UnitTypes::Terran_Starport) || BaseAgent::isOfType(type, UnitTypes::Terran_Command_Center) || BaseAgent::isOfType(type, UnitTypes::Terran_Science_Facility)) { x2 += 2; } Corners c; c.x1 = x1; c.y1 = y1; c.x2 = x2; c.y2 = y2; return c; }
void Squad::attack(TilePosition mGoal) { if (mGoal.x() == -1 || mGoal.y() == -1) return; if (currentState != STATE_ATTACK) { if (!isUnderAttack()) { if (isActive()) { currentState = STATE_ATTACK; } } } if (isActive()) { setGoal(mGoal); } }
void Squad::assist(TilePosition mGoal) { if (mGoal.x() == -1 || mGoal.y() == -1) return; if (currentState != STATE_ASSIST) { if (!isUnderAttack() && currentState == STATE_DEFEND) { currentState = STATE_ASSIST; setGoal(mGoal); } } else { if (goal.x() == -1) { setGoal(mGoal); } } }
BaseClass::BaseClass(TilePosition position, const UnitGroup &resources, Region region, std::set<TilePosition> tiles, bool startLocation) : mCenterTilePosition(position) , mCenterPosition(Position(position.x()*32+64, position.y()*32+48)) , mMinedOut(false) , mRegion(region) , mIsStartLocation(startLocation) , mPlayer(NULL) , mBuildings() , mTiles(tiles) , mIsUnderAttack(false) , mIsContested(false) , mTechBuildings(0) { for each(Unit resource in resources) { if(resource->getType() == BWAPI::UnitTypes::Resource_Mineral_Field) mMinerals.insert(resource); else mGeysers.insert(resource); } }
void Squad::setGoal(TilePosition mGoal) { if (isAttacking()) { if (goal.x() != -1) { return; } } if (mGoal.x() != goal.x() || mGoal.y() != goal.y()) { goalSetFrame = Broodwar->getFrameCount(); if (isGround()) { int d = (int)goal.getDistance(mGoal); if (d >= 10) { if ((int)agents.size() > 0) { Pathfinder::Instance().requestPath(getCenter(), mGoal); if (!Pathfinder::Instance().isReady(getCenter(), mGoal)) { return; } path = Pathfinder::Instance().getPath(getCenter(), mGoal); arrivedFrame = -1; pathIndex = 10; if (path.size() == 0) return; } } } this->goal = mGoal; setMemberGoals(goal); } }
void Commander::forceAttack() { TilePosition cGoal = getClosestEnemyBuilding(Broodwar->self()->getStartLocation()); Broodwar->printf("[%d] Launch attack (%d,%d)", Broodwar->getFrameCount(), cGoal.x(), cGoal.y()); if (cGoal.x() == -1) { return; } for (int i = 0; i < (int)squads.size(); i++) { if (squads.at(i)->isOffensive() || squads.at(i)->isSupport()) { if (cGoal.x() >= 0) { squads.at(i)->forceActive(); squads.at(i)->attack(cGoal); } } } currentState = ATTACK; }
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; }
int ExplorationManager::getLastVisitFrame(BWTA::Region* region) { for (int i = 0; i < (int)exploreData.size(); i++) { if (exploreData.at(i).matches(region)) { //Check if region is visible. If so, set lastVisitFrame to now if (Broodwar->isVisible(exploreData.at(i).center)) { exploreData.at(i).lastVisitFrame = Broodwar->getFrameCount(); } return exploreData.at(i).lastVisitFrame; } } //Error: No region found TilePosition goal = TilePosition(region->getCenter()); Broodwar->printf("FATAL GetLastVF: Unable to find region for tile (%d,%d)", goal.x(), goal.y()); return -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); }
void Mentat::onFrame() { if (analyzed) { //we will iterate through all the base locations, and draw their outlines. for( set<BWTA::BaseLocation*>::const_iterator i = BWTA::getBaseLocations().begin(); i != BWTA::getBaseLocations().end(); i++) { TilePosition p = (*i)->getTilePosition(); Position base = (*i)->getPosition(); //draw outline of center location Broodwar->drawBox(CoordinateType::Map,p.x() * 32, p.y() * 32, p.x() * 32 + 4 * 32, p.y() * 32 + 3 * 32, Colors::Blue, false); //draw a circle at each mineral patch for( set<BWAPI::Unit*>::const_iterator j = (*i)->getStaticMinerals().begin(); j != (*i)->getStaticMinerals().end(); j++) { Position mineral = (*j)->getInitialPosition(); Broodwar->drawCircle(CoordinateType::Map, mineral.x(), mineral.y(), 30, Colors::Cyan, false); } //draw the outlines of vespene geysers for( set<BWAPI::Unit*>::const_iterator j = (*i)->getGeysers().begin(); j != (*i)->getGeysers().end(); j++) { TilePosition vespene = (*j)->getInitialTilePosition(); Broodwar->drawBox(CoordinateType::Map,vespene.x() * 32, vespene.y() * 32, vespene.x() * 32 + 4 * 32, vespene.y() * 32 + 2 * 32, Colors::Orange, false); } //if this is an island expansion, draw a yellow circle around the base location if ( (*i)->isIsland() ) { Broodwar->drawCircle(CoordinateType::Map, base.x(), base.y(), 80, Colors::Yellow, false); } } //we will iterate through all the regions and draw the polygon outline of it in green. for( set<BWTA::Region*>::const_iterator i = BWTA::getRegions().begin(); i != BWTA::getRegions().end(); i++) { BWTA::Polygon region = (*i)->getPolygon(); for( int j = 0; j<(int)region.size(); j++ ) { Position point1 = region[j]; Position point2 = region[(j + 1) % region.size()]; Broodwar->drawLine(CoordinateType::Map, point1.x(), point1.y(), point2.x(), point2.y(), Colors::Green); } } //we will visualize the chokepoints with red lines for( set<BWTA::Region*>::const_iterator i = BWTA::getRegions().begin(); i != BWTA::getRegions().end(); i++) { for( set<BWTA::Chokepoint*>::const_iterator j = (*i)->getChokepoints().begin(); j != (*i)->getChokepoints().end(); j++) { Position point1 = (*j)->getSides().first; Position point2 = (*j)->getSides().second; Broodwar->drawLine(CoordinateType::Map, point1.x(), point1.y(), point2.x(), point2.y(), Colors::Red); } } } if (analysis_just_finished) { Broodwar->printf("Finished analyzing map."); analysis_just_finished = false; } }
//---------------------------------------------------------------------------------------------------------- TilePosition TilePosition::operator-(const TilePosition& position) const { return TilePosition(this->x() - position.x(), this->y() - position.y()); }
//---------------------------------------------- OPERATOR < ------------------------------------------------ bool TilePosition::operator < (const TilePosition& TilePosition) const { return this->x() < TilePosition.x() || (this->x() == TilePosition.x() && this->y() < TilePosition.y()); }
//---------------------------------------------- OPERATOR != ----------------------------------------------- bool TilePosition::operator != (const TilePosition& TilePosition) const { return this->x() != TilePosition.x() || this->y() != TilePosition.y(); }
BuildTilePath PathFinderClass::CreateTilePath(TilePosition start, TilePosition target, std::tr1::function<bool (TilePosition)> tileTest, std::tr1::function<int (TilePosition, TilePosition, int)> gFunction, std::tr1::function<int (TilePosition, TilePosition)> hFunction, int maxGValue, bool diaganol) { BuildTilePath path; Heap<TilePosition, int> openTiles(true); std::map<TilePosition, int> gmap; std::map<TilePosition, TilePosition> parent; std::set<TilePosition> closedTiles; openTiles.push(std::make_pair(start, 0)); gmap[start] = 0; parent[start] = start; while(!openTiles.empty()) { TilePosition p = openTiles.top().first; int gvalue = gmap[p]; if(p == target || (maxGValue != 0 && gvalue >= maxGValue)) break; int fvalue = openTiles.top().second; openTiles.pop(); closedTiles.insert(p); int minx = std::max(p.x() - 1, 0); int maxx = std::min(p.x() + 1, BWAPI::Broodwar->mapWidth()); int miny = std::max(p.y() - 1, 0); int maxy = std::min(p.y() + 1, BWAPI::Broodwar->mapHeight()); for(int x = minx; x <= maxx; x++) { for(int y = miny; y <= maxy; y++) { if (x != p.x() && y != p.y() && !diaganol) continue; TilePosition t(x, y); if (closedTiles.find(t) != closedTiles.end()) continue; if(!tileTest(t)) continue; int g = gFunction(t, p, gvalue); int f = g + hFunction(t, target); if (gmap.find(t) == gmap.end() || g < gmap.find(t)->second) { gmap[t] = g; openTiles.set(t, f); parent[t] = p; } } } } if(!openTiles.empty()) { TilePosition p = openTiles.top().first; while(p != parent[p]) { path.addNode(p); p = parent[p]; } path.addNode(start); path.isComplete = true; } return path; }
//---------------------------------------------- OPERATOR == ----------------------------------------------- bool TilePosition::operator == (const TilePosition& TilePosition) const { return this->x() == TilePosition.x() && this->y() == TilePosition.y(); }