/**
  * Counts the barracks constructed or under construction around a command center
  */
int ExampleAIModule::calculateBarracksFromCommandCenter(Unit cmdCenter) {

	//first: count built barracks around the command center
	Position commandCenterPos = cmdCenter->getPosition();
	
	Unitset units = Broodwar->getUnitsInRadius(commandCenterPos, BASE_RADIUS);
	int builtBarracks = 0;
	for ( Unitset::iterator u = units.begin(); u != units.end(); ++u ) {
		if ( u->getType() == UnitTypes::Terran_Barracks && u->isCompleted()) {
			builtBarracks++;
		}
	}
	
	//second: count the SCVs constructing around the command center
	int scheduledForConstruction = 0;
	for(auto scv = scvMap.begin(); scv != scvMap.end(); scv++){
		//if SCV is not constructing the barracks but is moving towards it...
		if(scv->second->state == BUILDING_BARRACKS && Position(scv->second->newBuildingLocation).getApproxDistance(commandCenterPos) < BASE_RADIUS ){
			
			Broodwar->drawCircleMap(scv->second->gameUnit->getPosition(),20,Color(Colors::Cyan));
			scheduledForConstruction++;
		}
	}
	//Broodwar->sendText("%d - %d",builtBarracks,scheduledForConstruction);
	return builtBarracks + scheduledForConstruction;
}
Exemple #2
0
 Unitset Playerset::getUnits() const
 {
   Unitset retSet;
   for (auto &p : *this)
   {
     auto units = p->getUnits();
     retSet.insert(units.begin(), units.end());
   }
   return retSet;
 }
Exemple #3
0
bool Bases::needsAssimilator()
{
	Unitset us;
	for (auto br : bRec)
	{
		if (br.AssimilatorID == -1)
		{
			us = Broodwar->getUnitsInRadius(Broodwar->getUnit(br.NexusID)->getPosition(), 480, Filter::IsWorker);
			if (us.size() > 10)
				return true;
		}
	}
	return false;
}
Exemple #4
0
//----------------------------------------------------------------------------------------------
MapArea StarCraftMap::GetSpecialBuildingPosition(EntityClassType p_buildingType) const
{
    if (!m_isOnline)
        DEBUG_THROW(InvalidOperationException(XcptHere));

    MapArea candidatePosition = MapArea::Null();

    // Get the player base tile position
    MapArea colony = g_Game->Self()->GetColonyMapArea();
    Vector2 colonyTile = colony.Pos();

    // Get the unit type object
    UnitType type;
    TID unitTypeId;
    string typeName;
    unitTypeId = g_Database.EntityMapping.GetBySecond(p_buildingType);
    typeName = g_Database.EntityIdentMapping.GetByFirst(unitTypeId);
    type = BWAPI::UnitType::getType(typeName);

    if (type.isRefinery())
    {
        int bestDistance = INT_MAX;
        Unitset geysers = Broodwar->getGeysers();
        Unit currentGeyser;

        for (unsigned i = 0; i < geysers.size(); ++i)
        {
            currentGeyser = geysers[i];
            Vector2 currentPosition = Vector2(
                                          UnitPositionFromTilePosition(currentGeyser->getTilePosition().x),
                                          UnitPositionFromTilePosition(currentGeyser->getTilePosition().y));
            int currentDistance = colonyTile.Distance(currentPosition);

            if (currentDistance <= bestDistance)
            {
                bestDistance = currentDistance;
                candidatePosition = MapArea(
                                        currentPosition,
                                        type.tileWidth(),
                                        type.tileHeight());
            }
        }
        _ASSERTE(CanBuildHere(candidatePosition.Pos(), p_buildingType));
    }

    return candidatePosition;
}
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
}
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
}
		// Methods
void Commander::init()
{
	// Enemy units
	Unitset tmpEnemyUnit = Broodwar->enemy()->getUnits();
	for(auto i=tmpEnemyUnit.begin();i!=tmpEnemyUnit.end();++i)
	{
		if(i->getType()==UnitTypes::Terran_Marine)
		{
			OUnit* oUnit = OUnit::get(*i);
			oAllUnits.insert(oUnit);
		}
	}

	// Create squad of 'nbUnitPerSquad' units
	Unitset allGameUnit = Broodwar->self()->getUnits();
	int indexInSquad = 0;
	std::set<PUnit*> squadUnits;
	for(auto i=allGameUnit.begin();i!=allGameUnit.end();++i)
	{
		if(i->getType()==UnitTypes::Terran_Marine)
		{
			PUnit* pUnit = PUnit::get(*i);
			if(indexInSquad >= nbUnitPerSquad)
			{
				indexInSquad=0;
				SquadManager* newSquad = new SquadManager();
				for(auto currentUnit = squadUnits.begin(); currentUnit!=squadUnits.end();currentUnit++)
					newSquad->addUnit(*currentUnit);
				squads.insert(newSquad);
				squadUnits.clear();
			}
			squadUnits.insert(pUnit);
			indexInSquad++;
		}
	}

	if(!squadUnits.empty()) // In case of a non full squad
	 {
	 	SquadManager* newSquad = new SquadManager();
	 	for(auto currentUnit = squadUnits.begin(); currentUnit!=squadUnits.end();currentUnit++)
	 		newSquad->addUnit(*currentUnit);
	 	squads.insert(newSquad);
	 }

	// Add a 'brain' to a squad
	for(auto i=squads.begin(); i!=squads.end();++i)
	{
		if((*i)->brain == nullptr)
			(*i)->brain = (new ParallelNode())
							->addChild((new RepeatNode(-1))
								->addChild(new BoolCondition<SquadManager>(&SquadManager::isInPosition,true))
								->addChild(new SquadFire()))
							->addChild(new MoveSquadToPosition());
	}

	// My units
	for(auto i=allGameUnit.begin();i!=allGameUnit.end();++i)
	{
		PUnit* pUnit = PUnit::get(*i);

		if(i->getType()==UnitTypes::Terran_Marine)
			pAllUnits.insert(pUnit);
	}
}
void Unitset::insert(const Unitset& container) {
	set.insert(container.begin(), container.end());
}
Exemple #9
0
int main(int argc, const char* argv[])
{
  std::cout << "Connecting..." << std::endl;;
  reconnect();
  while(true)
  {
    std::cout << "waiting to enter match" << std::endl;
    while ( !Broodwar->isInGame() )
    {
      BWAPI::BWAPIClient.update();
      if (!BWAPI::BWAPIClient.isConnected())
      {
        std::cout << "Reconnecting..." << std::endl;;
        reconnect();
      }
    }
    std::cout << "starting match!" << std::endl;
    Broodwar->sendText("Hello world!");
    Broodwar << "The map is " << Broodwar->mapName() << ", a " << Broodwar->getStartLocations().size() << " player map" << std::endl;
    // Enable some cheat flags
    Broodwar->enableFlag(Flag::UserInput);
    // Uncomment to enable complete map information
    //Broodwar->enableFlag(Flag::CompleteMapInformation);
   
    show_bullets=false;
    show_visibility_data=false;

    if (Broodwar->isReplay())
    {
      Broodwar << "The following players are in this replay:" << std::endl;;
      Playerset players = Broodwar->getPlayers();
      for(Playerset::iterator p = players.begin(); p != players.end(); ++p )
      {
        if ( !p->getUnits().empty() && !p->isNeutral() )
          Broodwar << p->getName() << ", playing as " << p->getRace() << std::endl;
      }
    }
    else
    {
      Broodwar << "The match up is " << Broodwar->self()->getRace() << " vs " << Broodwar->enemy()->getRace() << std::endl;

      //send each worker to the mineral field that is closest to it
      Unitset units    = Broodwar->self()->getUnits();
      Unitset minerals  = Broodwar->getMinerals();
      for ( Unitset::iterator i = units.begin(); i != units.end(); ++i )
      {
        if ( i->getType().isWorker() )
        {
          Unit closestMineral = NULL;

          for( Unitset::iterator m = minerals.begin(); m != minerals.end(); ++m )
          {
            if ( !closestMineral || i->getDistance(*m) < i->getDistance(closestMineral))
              closestMineral = *m;
          }
          if ( closestMineral )
            i->rightClick(closestMineral);
        }
        else if ( i->getType().isResourceDepot() )
        {
          //if this is a center, tell it to build the appropiate type of worker
          i->train(Broodwar->self()->getRace().getWorker());
        }
      }
    }
    while(Broodwar->isInGame())
    {
      for(std::list<Event>::const_iterator e = Broodwar->getEvents().begin(); e != Broodwar->getEvents().end(); ++e)
      {
        switch(e->getType())
        {
          case EventType::MatchEnd:
            if (e->isWinner())
              Broodwar << "I won the game" << std::endl;
            else
              Broodwar << "I lost the game" << std::endl;
            break;
          case EventType::SendText:
            if (e->getText()=="/show bullets")
            {
              show_bullets=!show_bullets;
            } else if (e->getText()=="/show players")
            {
              showPlayers();
            } else if (e->getText()=="/show forces")
            {
              showForces();
            } else if (e->getText()=="/show visibility")
            {
              show_visibility_data=!show_visibility_data;
            } 
            else
            {
              Broodwar << "You typed \"" << e->getText() << "\"!" << std::endl;
            }
            break;
          case EventType::ReceiveText:
            Broodwar << e->getPlayer()->getName() << " said \"" << e->getText() << "\"" << std::endl;
            break;
          case EventType::PlayerLeft:
            Broodwar << e->getPlayer()->getName() << " left the game." << std::endl;
            break;
          case EventType::NukeDetect:
            if (e->getPosition()!=Positions::Unknown)
            {
              Broodwar->drawCircleMap(e->getPosition(), 40, Colors::Red, true);
              Broodwar << "Nuclear Launch Detected at " << e->getPosition() << std::endl;
            }
            else
              Broodwar << "Nuclear Launch Detected" << std::endl;
            break;
          case EventType::UnitCreate:
            if (!Broodwar->isReplay())
              Broodwar << "A " << e->getUnit()->getType() << " [" << e->getUnit() << "] has been created at " << e->getUnit()->getPosition() << std::endl;
            else
            {
              // if we are in a replay, then we will print out the build order
              // (just of the buildings, not the units).
              if (e->getUnit()->getType().isBuilding() && e->getUnit()->getPlayer()->isNeutral()==false)
              {
                int seconds=Broodwar->getFrameCount()/24;
                int minutes=seconds/60;
                seconds%=60;
                Broodwar->sendText("%.2d:%.2d: %s creates a %s", minutes, seconds, e->getUnit()->getPlayer()->getName().c_str(), e->getUnit()->getType().c_str());
              }
            }
            break;
          case EventType::UnitDestroy:
            if (!Broodwar->isReplay())
              Broodwar->sendText("A %s [%x] has been destroyed at (%d,%d)",e->getUnit()->getType().c_str(), e->getUnit(), e->getUnit()->getPosition().x, e->getUnit()->getPosition().y);
            break;
          case EventType::UnitMorph:
            if (!Broodwar->isReplay())
              Broodwar->sendText("A %s [%x] has been morphed at (%d,%d)",e->getUnit()->getType().c_str(), e->getUnit(), e->getUnit()->getPosition().x, e->getUnit()->getPosition().y);
            else
            {
              // if we are in a replay, then we will print out the build order
              // (just of the buildings, not the units).
              if (e->getUnit()->getType().isBuilding() && e->getUnit()->getPlayer()->isNeutral()==false)
              {
                int seconds=Broodwar->getFrameCount()/24;
                int minutes=seconds/60;
                seconds%=60;
                Broodwar->sendText("%.2d:%.2d: %s morphs a %s" ,minutes, seconds, e->getUnit()->getPlayer()->getName().c_str(), e->getUnit()->getType().c_str());
              }
            }
            break;
          case EventType::UnitShow:
            if (!Broodwar->isReplay())
              Broodwar->sendText("A %s [%x] has been spotted at (%d,%d)", e->getUnit()->getType().c_str(), e->getUnit(), e->getUnit()->getPosition().x, e->getUnit()->getPosition().y);
            break;
          case EventType::UnitHide:
            if (!Broodwar->isReplay())
              Broodwar->sendText("A %s [%x] was last seen at (%d,%d)", e->getUnit()->getType().c_str(), e->getUnit(), e->getUnit()->getPosition().x, e->getUnit()->getPosition().y);
            break;
          case EventType::UnitRenegade:
            if (!Broodwar->isReplay())
              Broodwar->sendText("A %s [%x] is now owned by %s", e->getUnit()->getType().c_str(), e->getUnit(), e->getUnit()->getPlayer()->getName().c_str());
            break;
          case EventType::SaveGame:
            Broodwar->sendText("The game was saved to \"%s\".", e->getText().c_str());
            break;
        }
      }

      if (show_bullets)
        drawBullets();

      if (show_visibility_data)
        drawVisibilityData();

      drawStats();
      Broodwar->drawTextScreen(300,0,"FPS: %f",Broodwar->getAverageFPS());

      BWAPI::BWAPIClient.update();
      if (!BWAPI::BWAPIClient.isConnected())
      {
        std::cout << "Reconnecting..." << std::endl;
        reconnect();
      }
    }
    std::cout << "Game ended" << std::endl;
  }
  std::cout << "Press ENTER to continue..." << std::endl;
  std::cin.ignore();
  return 0;
}
Exemple #10
0
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());
	}
}
Exemple #11
0
/**
  * Create new Tasks for each enemy units not covered by attack tasks
  * Cleans up attack tasks whose targets are not in position anymore
  * AttackTasks are added at onUnitDiscover()
  */
void ExampleAIModule::updateAttack(){
	//traverse the task list to check if positions are visible and still have enemies
	vector<Task>* preserved = new vector<Task>(); //stores the tasks that should not be removed
	UnitType marineType = UnitTypes::Terran_Marine;

	//Broodwar->drawTextScreen(200,120,"marine seek: %d // sight: %d", marineType.seekRange(), marineType.sightRange());
	
	for(auto task = allTasks[Attack]->begin(); task != allTasks[Attack]->end(); task++){

		if(Broodwar->isVisible(task->getPosition().x / TILE_SIZE , task->getPosition().y / TILE_SIZE)){
			Unitset inRange = Broodwar->getUnitsInRadius(task->getPosition(),  marineType.groundWeapon().maxRange(), Filter::IsEnemy);
			//Broodwar->sendText("%d in range of attack task.", inRange.size());
			
			// Check if the unit can be reached by the marines
			// Sometimes cloacked or burrowed units can be marked as enemy but it cannot be attacked
			bool onlyCloackedUnits = true;
			for(auto u = inRange.begin(); u != inRange.end(); ++u) {
				if(!u->isCloaked() && !u->isBurrowed() & !u->isInvincible()){
					onlyCloackedUnits = false;
					break;
				}
			}
			if (inRange.size() == 0 || onlyCloackedUnits) {
				Broodwar->sendText("Attack task removed");
				//toDelete.push_back(*task);
			}
			else {
				preserved->push_back(*task);
			}

		}
		else { //keeps invisible attack targets, so that they can be investigated
			preserved->push_back(*task);
		}
	}
	

	//brings preserved tasks to the main task vector
	allTasks[Attack]->swap(*preserved);
	delete preserved; //hope this doesn't invalidates tasks...
	//in this point, tasks whose targets are not visible were removed

	// --- Now, adds new tasks for enemy units not covered by existent attack tasks ---

	//obtains a list with all enemies from all players
	Playerset foes = Broodwar->enemies();
	Unitset enemyUnits;
	enemyUnits.clear();

	for(auto foe = foes.begin(); foe != foes.end(); ++foe){
		enemyUnits += foe->getUnits();
	}

	//Broodwar->drawTextScreen(250,45, "#foes: %d", enemyUnits.size());

	//adds a task with a position for every enemy unit in the task list
	for(auto foeUnit = enemyUnits.begin(); foeUnit != enemyUnits.end(); ++foeUnit) {
		bool inRange = false;

		//tests if unit is already included in the area of another 'attack' task
		for(auto task = allTasks[Attack]->begin(); task != allTasks[Attack]->end(); task++){
			//task->
			//foeUnit->getType().groundWeapon().maxRange();
			//PositionTask* atk = static_cast<PositionTask* >( &(*task)) ; 
			if(foeUnit->getDistance(task->getPosition()) < marineType.groundWeapon().maxRange()){
				inRange = true;
				break;
			}
		}

		// Hector : extra validation to ignore unreachable targets
		//TODO: test is reachable 
		Position foePos = foeUnit->getPosition();
		if(! inRange && !foeUnit->isCloaked() && !foeUnit->isBurrowed() && !foeUnit->isInvincible() && Broodwar->isWalkable(foePos.x / 8, foePos.y / 8)){
			Task* atk = new Task(Attack, .8f, foeUnit->getPosition());
			allTasks[Attack]->push_back(*atk);
			//Broodwar->sendText("Attack task added, pos=%d,%d // %d,%d ", unit->getPosition().x, unit->getPosition().y, atk->getPosition().x, atk->getPosition().y);
		}
	}

	/*
	//if unit is enemy, adds it to 'attack' task list, if it isn't in range of an attack task
	//it seems that it works only for buildings... must check for mobile enemy units
	if(unit->getPlayer() != Broodwar->self() && unit->getPlayer() != Broodwar->neutral()){ 
		bool inRange = false;

		//tests if unit is already included in the area of another 'attack' task
		for(auto task = allTasks[Attack]->begin(); task != allTasks[Attack]->end(); task++){
			//task->

			//PositionTask* atk = static_cast<PositionTask* >( &(*task)) ; 
			if(unit->getDistance(task->getPosition()) < 6*TILE_SIZE){
				inRange = true;
				break;
			}
		}

		if(! inRange){
			Task* atk = new Task(Attack, .8f, unit->getPosition());
			allTasks[Attack]->push_back(*atk);
			Broodwar->sendText("Attack task added, pos=%d,%d // %d,%d ", unit->getPosition().x, unit->getPosition().y, atk->getPosition().x, atk->getPosition().y);

			for(auto task = allTasks[Attack]->begin(); task != allTasks[Attack]->end(); task++){
				//PositionTask* atk = static_cast<PositionTask* >( &(*task)) ; 
				Broodwar->sendText("pos=%d,%d", task->getPosition().x, task->getPosition().y);
			}
		}

	}
	*/
}
Exemple #12
0
void ExampleAIModule::onFrame() {
	//TODO: set rally point of barracks to the nearest command center
	// Called once every game frame
	// Return if the game is paused
	if ( Broodwar->isPaused() )// || !Broodwar->self() )
		return;

	if (Broodwar->isReplay()){

		Playerset plrs = Broodwar->getPlayers();
		Playerset::iterator plr;

		Broodwar->drawTextScreen(290, 20, "Time: ~ %dh%dm%ds", Broodwar->elapsedTime() / 3600, Broodwar->elapsedTime() / 60, Broodwar->elapsedTime() % 60);
		
		int pCount = 1;
		for (plr = plrs.begin(); plr != plrs.end(); plr++, pCount++){
			Broodwar->drawTextScreen(290, 20 + (20 * pCount), "Score p%d - Unit, Building, Resource = %d, %d, %d ", pCount, plr->getUnitScore(), plr->getBuildingScore(), plr->gatheredMinerals() + plr->gatheredGas());
		}
		return;
	}

	_drawStats();

	// Draw bullets
	/*Bulletset bullets = Broodwar->getBullets();
	for(Bulletset::iterator i = bullets.begin(); i != bullets.end(); ++i){
		Position p = i->getPosition();
		double velocityX = i->getVelocityX();
		double velocityY = i->getVelocityY();
		Broodwar->drawLineMap(p, p + Position((int)velocityX, (int)velocityY), i->getPlayer() == Broodwar->self() ? Colors::Green : Colors::Red);
		//Broodwar->drawTextMap(p, "%c%s", i->getPlayer() == Broodwar->self() ? Text::Green : Text::Red, i->getType().c_str());
	}*/

	// 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;

	// reinsert tasks to prevent errors
	if(allTasks[BuildCommandCenter]->size() <= 0){
		allTasks[BuildCommandCenter]->push_back(Task(BuildCommandCenter, 0));
		buildCommandCenter = &allTasks[BuildCommandCenter]->at(0);
	}
	if(allTasks[BuildSupplyDepot]->size() <= 0){
		allTasks[BuildSupplyDepot]->push_back(Task(BuildSupplyDepot, 0));
		buildSupplyDepot = &allTasks[BuildSupplyDepot]->at(0);
	}
	if(allTasks[Explore]->size() <= 0){
		allTasks[Explore]->push_back(Task(Explore, 0));
		explore = &allTasks[Explore]->at(0);
	}
	
	//sets all rally points of barracks to the nearest command center
	for(auto c = commandCenters.begin(); c != commandCenters.end(); c++){
		Unitset brk = c->getUnitsInRadius(BASE_RADIUS, Filter::IsOwned);

		for (auto b = brk.begin(); b != brk.end(); b++){
			if(b->getType() != UnitTypes::Terran_Barracks || !b->isCompleted()){
				continue;
			}
			b->setRallyPoint(*c);
		}

	}

	//gives up the construction of buildings about to be destroyed
	Unitset all = Broodwar->self()->getUnits();
	for(auto b = all.begin(); b != all.end(); b++){
		//cancels construction if building is incomplete, is under attack and its hit points are low
		if (b->getType().isBuilding() && !b->isCompleted() && b->isUnderAttack() && b->getHitPoints() < .15f * b->getType().maxHitPoints()){
			b->cancelConstruction();
			//Broodwar << "construction canceled" << endl;
		}
	}


	updateTasks();

	_commanderAgent->onFrame(allTasks, trainSCVIncentives);

	//iterates through all marines
	for(auto marine = marines.begin(); marine != marines.end(); marine++){
		marine->second->onFrame(allTasks, marines);
	}

	// Iterate through all the SCV on the map
	unordered_map<int, SCVAgent*>::iterator it = scvMap.begin();
	for(unordered_map<int, SCVAgent*>::iterator iter = scvMap.begin(); iter != scvMap.end(); ++iter){
		int unitId =  iter->first;
		SCVAgent* agent = iter->second;
		Unit u = agent->getUnit();

		agent->onFrame(&allTasks, discoveredMineralPositions, commandCenters, scvMap);

		//Broodwar->drawTextMap(u->getPosition().x, u->getPosition().y, "agentId[%d]", unitId);

		/*if ( u->isLockedDown() || u->isMaelstrommed() || u->isStasised() )
			continue;
		
		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
		*/
	}
	
	/*Broodwar->drawTextScreen(20, 90 + yOffset, "Number of SCV in map [%d]", 
		Text::White, scvMap->size()
	);*/
}
Exemple #13
0
void MeleeAgent::onFrame() {
	if (!m_Unit->exists()) {
		if (m_Target != TilePositions::Invalid) {
			Blackboard::Instance().removeScoutAssignment(m_Target);
			m_Target = TilePositions::Invalid;
		}
	}

	if (m_Unit->getLastCommandFrame() + std::max(10, Broodwar->getLatencyFrames()) >= Broodwar->getFrameCount() || !m_Unit->canCommand()) {
		return;
	}
	else {
		if (m_Unit->isAttacking()) {
			Blackboard::Instance().markUnitForAttack(m_Unit->getOrderTarget());
		}
	}

	if (m_Target != TilePositions::Invalid && m_Unit->getDistance(Position(m_Target)) < m_Unit->getType().sightRange()) {
		Blackboard::Instance().removeScoutingLocation(m_Target);
		m_Target = TilePositions::Invalid;
		return;
	}

	Unit closestEnemy = Broodwar->getClosestUnit(m_Unit->getPosition(), IsEnemy && IsDetected && !IsFlying && IsAttacking);
	if (m_Unit->isInWeaponRange(closestEnemy)) {
		Blackboard::Instance().markUnitForAttack(closestEnemy);
		m_Unit->attack(closestEnemy);
		return;
	}

	const Unitset nearbyUnits = Broodwar->getUnitsInRadius(m_Unit->getPosition(), 300);

	double confidence = 0;
	double caution = 0;

	for (const Unit u : nearbyUnits) {
		if (u->getPlayer()->getID() == Broodwar->self()->getID()) {
			double addConfidence = (u->getType().mineralPrice() + u->getType().gasPrice() * 2) * (u->getHitPoints() + u->getShields()) / (u->getType().maxHitPoints() + u->getType().maxShields());
			if (u->getType() == UnitTypes::Zerg_Zergling) {
				addConfidence /= 2;
			}
			confidence += addConfidence;
		}
		else if (u->getPlayer()->isEnemy(Broodwar->self())) {
			if (!u->getType().canAttack()) {
				continue;
			}

			double addCaution = (u->getType().mineralPrice() + u->getType().gasPrice() * 2) * (u->getHitPoints() + u->getShields()) / (u->getType().maxHitPoints() + u->getType().maxShields());
			if (u->getType().isWorker()) {
				addCaution /= 6;
			}
			else if (u->getType() == UnitTypes::Zerg_Zergling) {
				addCaution /= 2;
			}

			caution += addCaution;
		}
	}

	if (caution < lastCaution) {
		caution = 0.9 * lastCaution + 0.1 * caution;
	}
	lastCaution = caution;

	Unitset attackers = Broodwar->getUnitsInRadius(m_Unit->getPosition(), 300, IsEnemy && IsAttacking && OrderTarget == m_Unit);
	if (!attackers.empty() || caution >= Blackboard::Instance().getDouble("ConfidenceFactor") * confidence) {
		m_Unit->move(Position(Broodwar->self()->getStartLocation()));
		return;
	}

	if (Broodwar->getFrameCount() - lastTargetAcquired > 24 * 2) {
		toAttack = Broodwar->getBestUnit([&](const Unit best, const Unit cur) -> Unit {
			if (cur->getType().canAttack() && m_Unit->isInWeaponRange(cur) && !(m_Unit->isInWeaponRange(best))) return cur;
			if (best->getType().canAttack() && !m_Unit->isInWeaponRange(cur) && (m_Unit->isInWeaponRange(cur))) return best;

			const int attackingBest = Blackboard::Instance().getUnitsAttackingCount(best);
			const int attackingCur = Blackboard::Instance().getUnitsAttackingCount(cur);

			if (attackingBest < getIdealNumberOfAttackers(best) && attackingCur >= getIdealNumberOfAttackers(cur)) return best;
			if (attackingBest >= getIdealNumberOfAttackers(best) && attackingCur < getIdealNumberOfAttackers(cur)) return cur;

			if (attackingBest > attackingCur) return best;
			if (attackingBest < attackingCur) return cur;

			const double bestScore = calcScore(m_Unit, best);
			const double curScore = calcScore(m_Unit, cur);

			if (bestScore > curScore) return best;
			if (curScore > bestScore) return cur;

			// TODO: More criteria? Is it likely that the score won't suffice?
			return best;
		}, IsEnemy && IsDetected && !IsFlying && GetType != UnitTypes::Zerg_Larva);

		lastTargetAcquired = Broodwar->getFrameCount();
	}

	if (toAttack && toAttack->exists() && Blackboard::Instance().getUnitsAttackingCount(toAttack) < getIdealNumberOfAttackers(toAttack)) {
		Blackboard::Instance().markUnitForAttack(toAttack);
		Attack(toAttack);
		return;
	}

	TilePosition ebpos = Blackboard::Instance().getEnemyBuildingPosition();
	if (ebpos != TilePositions::Invalid) {
		Move(Position(ebpos));
		return;
	}

	if (m_Target == TilePositions::Invalid || lastScoutValidity < Blackboard::Instance().scoutingValidityIndex()) {
		if (m_Target != TilePositions::Invalid) {
			Blackboard::Instance().removeScoutAssignment(m_Target);
		}
		m_Target = Blackboard::Instance().getScoutAssignment(m_Unit->getTilePosition());

		if (!Broodwar->hasPath(m_Unit->getPosition(), Position(m_Target))) {
			Blackboard::Instance().removeScoutAssignment(m_Target);
			m_Target = TilePositions::Invalid;
		}

		lastScoutValidity = Blackboard::Instance().scoutingValidityIndex();
	}

	if (m_Target == TilePositions::Invalid) {
		m_Target = TilePosition(BWEM::Map::Instance().RandomPosition());
	}

	Move(Position(m_Target));
}