void ExampleAIModule::updateBuildCommandCenter(){ //if we don't have enough minerals for a CMD center, sets zero incentive if (Broodwar->self()->minerals() < UnitTypes::Terran_Command_Center.mineralPrice()){ buildCommandCenter->setIncentive(0.0f); return; } /*if(buildCommandCenter->getIncentive() > 0) { if(scvMap[3] != NULL){ scvMap[3]->buildCommandCenter(discoveredMinerals, commandCenters); } }*/ //for every discovered mineral, check if it is in range of a command center for(auto mPos = discoveredMineralPositions.begin(); mPos != discoveredMineralPositions.end(); ++mPos){ bool reachable = false; for(Unitset::iterator cmd = commandCenters.begin(); cmd != commandCenters.end(); ++cmd){ if (cmd->getPosition().getApproxDistance(*mPos) < BASE_RADIUS){ reachable = true; break; } } if (!reachable){ buildCommandCenter->setIncentive(0.8f); return; } } buildCommandCenter->setIncentive(0); }
void ExampleAIModule::updateTrainSCV(){ for(Unitset::iterator cmd = commandCenters.begin(); cmd != commandCenters.end(); ++cmd){ Unitset mineralsAround = Broodwar->getUnitsInRadius(cmd->getPosition(), BASE_RADIUS, Filter::IsMineralField); Unitset scvAround = Broodwar->getUnitsInRadius(cmd->getPosition(), BASE_RADIUS, Filter::IsWorker && Filter::IsOwned); trainSCVIncentives[*cmd] = max(0.0f, 1.0f - (scvAround.size() / (2.5f * mineralsAround.size()))); /* from medic-branch if(scvMap.size() < 110){ trainSCVIncentives[*cmd] = max(0.0f, 1.0f - (scvAround.size() / (2.5f * mineralsAround.size()))); } else{ trainSCVIncentives[*cmd] = 0.0f; }*/ } //Broodwar->getu }
////////////////////////////////////////////////////////// Position Position Unitset::getPosition() const { // Declare the local position Position retPosition(0,0); unsigned int validPosCount = 0; // Add up the positions for all units in the set for ( Unitset::iterator i = this->begin(); i != this->end(); ++i ) { Position pos(i->getPosition()); if ( pos.isValid() ) { retPosition += pos; ++validPosCount; } } // Divides the position by the size of the set and returns it retPosition /= validPosCount; return retPosition; }
void ExampleAIModule::updateBuildBarracks(){ //calculates the number of barracks around the command center vector<Task>* newBarracksNeeded = new vector<Task>(); for (Unitset::iterator c = commandCenters.begin(); c != commandCenters.end(); c++){ int barracksNumber = calculateBarracksFromCommandCenter(Broodwar->getUnit(c->getID())); float incentive = max(0.0f, 1.0f - barracksNumber/3.0f); //sets incentive to ZERO if we have not enough minerals if(Broodwar->self()->minerals() < UnitTypes::Terran_Barracks.mineralPrice()){ incentive = 0.0f; } //updates the number of barracks around all command centers //builtBarracks[*c] = barracksNumber; //buildBarracksIncentives[*c] = incentive; newBarracksNeeded->push_back(Task(BuildBarracks, incentive, c->getPosition())); } allTasks[BuildBarracks]->swap(*newBarracksNeeded); delete newBarracksNeeded; //hope this doesn't invalidates the barracks }
void ExampleAIModule::onFrame() { // Called once every game frame // Display the game frame rate as text in the upper left area of the screen Broodwar->drawTextScreen(200, 0, "FPS: %d", Broodwar->getFPS() ); Broodwar->drawTextScreen(200, 20, "Average FPS: %f", Broodwar->getAverageFPS() ); // Return if the game is a replay or is paused if ( Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self() ) return; // Prevent spamming by only running our onFrame once every number of latency frames. // Latency frames are the number of frames before commands are processed. if ( Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0 ) return; // Iterate through all the units that we own Unitset myUnits = Broodwar->self()->getUnits(); for ( Unitset::iterator u = myUnits.begin(); u != myUnits.end(); ++u ) { // Ignore the unit if it no longer exists // Make sure to include this block when handling any Unit pointer! if ( !u->exists() ) continue; // Ignore the unit if it has one of the following status ailments if ( u->isLockedDown() || u->isMaelstrommed() || u->isStasised() ) continue; // Ignore the unit if it is in one of the following states if ( u->isLoaded() || !u->isPowered() || u->isStuck() ) continue; // Ignore the unit if it is incomplete or busy constructing if ( !u->isCompleted() || u->isConstructing() ) continue; // Finally make the unit do some stuff! // If the unit is a worker unit if ( u->getType().isWorker() ) { // if our worker is idle if ( u->isIdle() ) { // Order workers carrying a resource to return them to the center, // otherwise find a mineral patch to harvest. if ( u->isCarryingGas() || u->isCarryingMinerals() ) { u->returnCargo(); } else if ( !u->getPowerUp() ) // The worker cannot harvest anything if it { // is carrying a powerup such as a flag // Harvest from the nearest mineral patch or gas refinery if ( !u->gather( u->getClosestUnit( IsMineralField || IsRefinery )) ) { // If the call fails, then print the last error message Broodwar << Broodwar->getLastError() << std::endl; } } // closure: has no powerup } // closure: if idle } else if ( u->getType().isResourceDepot() ) // A resource depot is a Command Center, Nexus, or Hatchery { // Order the depot to construct more workers! But only when it is idle. if ( u->isIdle() && !u->train(u->getType().getRace().getWorker()) ) { // If that fails, draw the error at the location so that you can visibly see what went wrong! // However, drawing the error once will only appear for a single frame // so create an event that keeps it on the screen for some frames Position pos = u->getPosition(); Error lastErr = Broodwar->getLastError(); Broodwar->registerEvent([pos,lastErr](Game*){ Broodwar->drawTextMap(pos, "%c%s", Text::White, lastErr.c_str()); }, // action nullptr, // condition Broodwar->getLatencyFrames()); // frames to run // Retrieve the supply provider type in the case that we have run out of supplies UnitType supplyProviderType = u->getType().getRace().getSupplyProvider(); static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if ( lastErr == Errors::Insufficient_Supply && lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(supplyProviderType) == 0 ) { lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit supplyBuilder = u->getClosestUnit( GetType == supplyProviderType.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); // If a unit was found if ( supplyBuilder ) { if ( supplyProviderType.isBuilding() ) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(supplyProviderType, supplyBuilder->getTilePosition()); if ( targetBuildLocation ) { // Register an event that draws the target build location Broodwar->registerEvent([targetBuildLocation,supplyProviderType](Game*) { Broodwar->drawBoxMap( Position(targetBuildLocation), Position(targetBuildLocation + supplyProviderType.tileSize()), Colors::Blue); }, nullptr, // condition supplyProviderType.buildTime() + 100 ); // frames to run // Order the builder to construct the supply structure supplyBuilder->build( supplyProviderType, targetBuildLocation ); } } else { // Train the supply provider (Overlord) if the provider is not a structure supplyBuilder->train( supplyProviderType ); } } // closure: supplyBuilder is valid } // closure: insufficient supply } // closure: failed to train idle unit } } // closure: unit iterator }
void ExampleAIModule::_drawStats(){ // Display the game frame rate as text in the upper left area of the screen Broodwar->drawTextScreen(290, 0, "FPS: %d", Broodwar->getFPS() ); Broodwar->drawTextScreen(290, 15, "Average FPS: %f", Broodwar->getAverageFPS() ); Broodwar->drawTextScreen(290, 30, "Frame count: %d", Broodwar->getFrameCount() ); Broodwar->drawTextScreen(290, 45, "Time: ~ %dh%dm%ds", Broodwar->elapsedTime() / 3600, Broodwar->elapsedTime() / 60, Broodwar->elapsedTime() % 60); _drawExploredStats(); // display some debug info... Broodwar->drawTextScreen(20, 0, "%cSupply Depot incentive = %.3f", Text::White, buildSupplyDepot->getIncentive() ); //Broodwar->sendText("%d", &allTasks[BuildSupplyDepot]->at(0) == buildSupplyDepot); Broodwar->drawTextScreen(20, 15, "%cExplore incentive = %.3f", Text::White, explore->getIncentive() ); Broodwar->drawTextScreen(20, 30, "%c#Marines: %d // #atk tasks: %d // Train incentive = %.3f", Text::White, marines.size(), allTasks[Attack]->size(), trainMarine->getIncentive() ); Broodwar->drawTextScreen(20, 45, "%c#SCVs: %d // Mine incentive = %.3f", Text::White, scvMap.size(), gatherMinerals->getIncentive() ); Broodwar->drawTextScreen(20, 60, "%cBuild CMD center incentive: %.3f", Text::White, buildCommandCenter->getIncentive() ); Broodwar->drawTextScreen(20, 75, "%cRepair tasks: %d", Text::White, allTasks[Repair]->size() ); Broodwar->drawTextScreen(20,90, "%cBrk inc. // SCV inc:", Text::White ); int yOffset = 0; /*for (Unitset::iterator cmd = commandCenters.begin(); cmd != commandCenters.end(); ++cmd){ Broodwar->drawTextScreen(20,90 + yOffset, "%c%d // %.2f // %.3f", Text::White, builtBarracks[*cmd], buildBarracksIncentives[*cmd], trainSCVIncentives[*cmd] ); yOffset += 15; }*/ for(auto brkTask = allTasks[BuildBarracks]->begin(); brkTask != allTasks[BuildBarracks]->end(); ++brkTask){ Unit cmdCenterAtPos = Broodwar->getUnitsInRadius(brkTask->getPosition(), 5)[0]; Broodwar->drawTextScreen(20,105 + yOffset, "%c%.2f // %.3f", Text::White, brkTask->getIncentive(), trainSCVIncentives[cmdCenterAtPos] ); yOffset += 15; } //draws the command center 'radius' for (Unitset::iterator c = commandCenters.begin(); c != commandCenters.end(); ++c){ Position commandCenterPos = c->getPosition(); //Unitset units = Broodwar->getUnitsInRadius(commandCenterPos, BASE_RADIUS*TILE_SIZE); Broodwar->drawCircleMap(commandCenterPos, BASE_RADIUS, Color(Colors::Blue)); } //draws a circle around the minerals Unitset minerals = Broodwar->getMinerals(); for (Unitset::iterator m = minerals.begin(); m != minerals.end(); ++m){ if (m->getType().isMineralField()) { Broodwar->drawCircleMap(m->getPosition(), m->getType().dimensionLeft(),Color(Colors::Blue)); } } //writes info under SCVS for(auto s = scvMap.begin(); s != scvMap.end(); s++){ Broodwar->drawTextMap(s->second->getUnit()->getPosition(), "ID[%d]", s->second->unitId); } //writes info under marines for(auto m = marines.begin(); m != marines.end(); m++){ Broodwar->drawTextMap(m->second->gameUnit->getPosition(), "ID[%d]", m->second->gameUnit->getID()); } //writes debug info under marines /*for(auto m = marines.begin(); m != marines.end(); ++m){ MarineAgent* mar = m->second; Broodwar->drawTextMap(mar->gameUnit->getPosition(),"%d,%d", mar->gameUnit->getPosition().x, mar->gameUnit->getPosition().y); }*/ //draws circles around Attack targets for(auto task = allTasks[Attack]->begin(); task != allTasks[Attack]->end(); task++){ Broodwar->drawCircleMap(task->getPosition(), UnitTypes::Terran_Marine.groundWeapon().maxRange(), Color(Colors::Red)); } //draws info under the buildings Unitset all = Broodwar->self()->getUnits(); for(auto bldg = all.begin(); bldg != all.end(); bldg++){ if( ! bldg->getType().isBuilding()){ continue; } string stat = ""; if(bldg->isBeingConstructed()){ stat = "Men at work"; } else if (!bldg->isCompleted()) { stat = "HALTED!"; } Broodwar->drawTextMap(bldg->getPosition(), stat.c_str()); } }