Пример #1
0
BWAPI::Position CombatCommander::getMainAttackLocation()
{
    BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

    // First choice: Attack an enemy region if we can see units inside it
    if (enemyBaseLocation)
    {
        BWAPI::Position enemyBasePosition = enemyBaseLocation->getPosition();

        // get all known enemy units in the area
        BWAPI::Unitset enemyUnitsInArea;
		MapGrid::Instance().GetUnits(enemyUnitsInArea, enemyBasePosition, 800, false, true);

        bool onlyOverlords = true;
        for (auto & unit : enemyUnitsInArea)
        {
            if (unit->getType() != BWAPI::UnitTypes::Zerg_Overlord)
            {
                onlyOverlords = false;
            }
        }

        if (!BWAPI::Broodwar->isExplored(BWAPI::TilePosition(enemyBasePosition)) || !enemyUnitsInArea.empty())
        {
            if (!onlyOverlords)
            {
                return enemyBaseLocation->getPosition();
            }
        }
    }

    // Second choice: Attack known enemy buildings
    for (const auto & kv : InformationManager::Instance().getUnitInfo(BWAPI::Broodwar->enemy()))
    {
        const UnitInfo & ui = kv.second;

        if (ui.type.isBuilding() && ui.lastPosition != BWAPI::Positions::None)
		{
			return ui.lastPosition;	
		}
    }

    // Third choice: Attack visible enemy units that aren't overlords
    for (auto & unit : BWAPI::Broodwar->enemy()->getUnits())
	{
        if (unit->getType() == BWAPI::UnitTypes::Zerg_Overlord)
        {
            continue;
        }

		if (UnitUtil::IsValidUnit(unit) && unit->isVisible())
		{
			return unit->getPosition();
		}
	}

    // Fourth choice: We can't see anything so explore the map attacking along the way
    return MapGrid::Instance().getLeastExplored();
}
Пример #2
0
BWAPI::TilePosition BuildingManager::getBuildingLocation(const Building & b)
{
    int numPylons = BWAPI::Broodwar->self()->completedUnitCount(BWAPI::UnitTypes::Protoss_Pylon);

    if (b.isGasSteal)
    {
        BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
        UAB_ASSERT(enemyBaseLocation,"Should have enemy base location before attempting gas steal");
        UAB_ASSERT(enemyBaseLocation->getGeysers().size() > 0,"Should have spotted an enemy geyser");

        for (auto & unit : enemyBaseLocation->getGeysers())
        {
            BWAPI::TilePosition tp(unit->getInitialTilePosition());
            return tp;
        }
    }

    if (b.type.requiresPsi() && numPylons == 0)
    {
        return BWAPI::TilePositions::None;
    }

    if (b.type.isRefinery())
    {
        return BuildingPlacer::Instance().getRefineryPosition();
    }

    if (b.type.isResourceDepot())
    {
        // get the location 
        BWAPI::TilePosition tile = MapTools::Instance().getNextExpansion();

        return tile;
    }

	if (b.type == BWAPI::UnitTypes::Terran_Bunker)
	{
		BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
		UAB_ASSERT(enemyBaseLocation, "Should have enemy base location before attempting gas steal");
		BWTA::Chokepoint * chokePoint = BWTA::getNearestChokepoint(enemyBaseLocation->getTilePosition());
		std::pair<BWAPI::Position, BWAPI::Position> sides = chokePoint->getSides();
		BWAPI::Position poi = enemyBaseLocation->getPosition().getDistance(sides.first) > enemyBaseLocation->getPosition().getDistance(sides.second) ? sides.first : sides.second;
		//BWAPI::Broodwar->printf("Tisssle Position (%d, %d)", BWAPI::TilePosition(poi).x, BWAPI::TilePosition(poi).y);
		return BWAPI::TilePosition(sides.second);
	}

    // set the building padding specifically
    int distance = b.type == BWAPI::UnitTypes::Protoss_Photon_Cannon ? 0 : Config::Macro::BuildingSpacing;
    if (b.type == BWAPI::UnitTypes::Protoss_Pylon && (numPylons < 3))
    {
        distance = Config::Macro::PylonSpacing;
    }

    // get a position within our region
    return BuildingPlacer::Instance().getBuildLocationNear(b,distance,false);
}
void CombatCommander::updateAttackSquads()
{
    Squad & mainAttackSquad = _squadData.getSquad("MainAttack");

	//check for overlord in squad
	bool containsoverlord = false;
	int numOverlords = 0;
	for (auto& unit : mainAttackSquad.getUnits()) {
		if (unit->getType() == BWAPI::UnitTypes::Zerg_Overlord)
		{
			containsoverlord = true;
			numOverlords++;
		}
	}

//	BWAPI::Broodwar->printf("Overlords in Attack squad: %d", numOverlords);

    for (auto & unit : _combatUnits)
    {

        if (unit->getType() == BWAPI::UnitTypes::Zerg_Scourge && UnitUtil::GetAllUnitCount(BWAPI::UnitTypes::Zerg_Hydralisk) < 30)
        {
            continue;
        }

        // get every unit of a lower priority and put it into the attack squad
		if (!unit->getType().isWorker() && (unit->getType() != BWAPI::UnitTypes::Zerg_Lurker) && _squadData.canAssignUnitToSquad(unit, mainAttackSquad))
		{
			if (unit->getType() == BWAPI::UnitTypes::Zerg_Overlord)
			{
				if (!containsoverlord && numOverlords < 2)
				{
					_squadData.assignUnitToSquad(unit, mainAttackSquad);
					containsoverlord = true;
					numOverlords++;
				}
			}
			else {
				_squadData.assignUnitToSquad(unit, mainAttackSquad);
			}
        }
    }


	// Defend bases until we have 3 lurkers
	if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg && mainAttackSquad.getUnits().size() < 10) {
		BWTA::BaseLocation * pos = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->self());
		SquadOrder mainAttackOrder(SquadOrderTypes::Defend, pos->getPosition(), 250, "Defend Region!");
		mainAttackSquad.setSquadOrder(mainAttackOrder);
		return;
	}

    SquadOrder mainAttackOrder(SquadOrderTypes::Attack, getMainAttackLocation(), 800, "Attack Enemy Base");
    mainAttackSquad.setSquadOrder(mainAttackOrder);
}
Пример #4
0
 void ScoutManager::onRevoke( BWAPI::Unit unit, double bid )
 {
   if ( m_scouts.find( unit ) != m_scouts.end() )
   {
     BWTA::BaseLocation* lostTarget = m_scouts[unit].m_target;
     if ( m_baseLocationsExplored.find( lostTarget ) == m_baseLocationsExplored.end() )
     {
       m_baseLocationsToScout.push_back( lostTarget );
       if ( m_debugMode )
       {
         BWAPI::Broodwar->printf( "Reassigning ( %d, %d )", lostTarget->getPosition().x, lostTarget->getPosition().y );
       }
     }
     m_scouts.erase( unit );
   }
 }
Пример #5
0
void InformationManager::checkEnemyMovedOut(){
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
	BWTA::BaseLocation * ourBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->self());
	BWAPI::TilePosition ourBase = BWAPI::TilePosition(ourBaseLocation->getPosition());
	if (enemyBaseLocation == nullptr)
	{
		double baseToBase = 0;
		if (_distToFarthestBase < 1.0)
		{
			double currentBtoB = 0;
			for (auto &bases : BWTA::getStartLocations())
			{
				currentBtoB = BWTA::getGroundDistance(ourBase, bases->getTilePosition());
				if (currentBtoB > baseToBase)
				{
					baseToBase = currentBtoB;
				}
			}
			_distToFarthestBase = baseToBase;
		}
		baseToBase = _distToFarthestBase;
		double baseToUnit;
		for (auto &unit : InformationManager::Instance().getUnitInfo(BWAPI::Broodwar->enemy()))
		{
			if (UnitUtil::IsCombatUnit(unit.second.unit))
			{
				BWAPI::TilePosition enemyPos = BWAPI::TilePosition(unit.second.lastPosition);
				if (_movedOutMap.count(enemyPos) != 0)
				{
					if (_movedOutMap[enemyPos] == true)
					{
						//BWAPI::Broodwar->printf("Enemy has moved out!");
						_enemyMovedOut = true;
						return;
					}
				}
				else
				{
					baseToUnit = BWTA::getGroundDistance(ourBase, BWAPI::TilePosition(unit.second.lastPosition));
					if (baseToUnit < baseToBase)
					{
						//BWAPI::Broodwar->printf("Enemy has moved out!");
						_enemyMovedOut = true;
						_movedOutMap[enemyPos] = true;
						return;
					}
					else
					{
						_movedOutMap[enemyPos] = false;
					}
				}
			}
		}
		_enemyMovedOut = false;
		//BWAPI::Broodwar->printf("Enemy in their base");
	}
	else
	{
		BWAPI::TilePosition enemyChoke = BWAPI::TilePosition(BWTA::getNearestChokepoint(enemyBaseLocation->getPosition())->getCenter());
		if (_distToEnemyChoke < 1.0)
		{
			_distToEnemyChoke = BWTA::getGroundDistance(ourBase, enemyChoke);
		}
		double baseToChoke = _distToEnemyChoke;
		double baseToUnit;
		for (auto &unit : InformationManager::Instance().getUnitInfo(BWAPI::Broodwar->enemy()))
		{
			if (UnitUtil::IsCombatUnit(unit.second.unit))
			{
				BWAPI::TilePosition enemyPos = BWAPI::TilePosition(unit.second.lastPosition);
				if (_movedOutMap.count(enemyPos) != 0)
				{
					if (_movedOutMap[enemyPos] == true)
					{
						//BWAPI::Broodwar->printf("Enemy has moved out!");
						_enemyMovedOut = true;
						return;
					}
				}
				else
				{
					baseToUnit = BWTA::getGroundDistance(ourBase, enemyPos);
					if (baseToUnit < baseToChoke)
					{
						//BWAPI::Broodwar->printf("Enemy has moved out!");
						_enemyMovedOut = true;
						_movedOutMap[enemyPos] = true;
						return;
					}
					else
					{
						_movedOutMap[enemyPos] = false;
					}
				}
			}
		}
		_enemyMovedOut = false;
		//BWAPI::Broodwar->printf("Enemy in their base");
	}
}
void ScoutManager::moveScouts()
{
	if (!_workerScout || !_workerScout->exists() || !(_workerScout->getHitPoints() > 0))
	{
		return;
	}

    int scoutHP = _workerScout->getHitPoints() + _workerScout->getShields();
    
    gasSteal();

	// get the enemy base location, if we have one
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

    int scoutDistanceThreshold = 30;

    if (_workerScout->isCarryingGas())
    {
        BWAPI::Broodwar->drawCircleMap(_workerScout->getPosition(), 10, BWAPI::Colors::Purple, true);
    }

    // if we initiated a gas steal and the worker isn't idle, 
    bool finishedConstructingGasSteal = _workerScout->isIdle() || _workerScout->isCarryingGas();
    if (!_gasStealFinished && _didGasSteal && !finishedConstructingGasSteal)
    {
        return;
    }
    // check to see if the gas steal is completed
    else if (_didGasSteal && finishedConstructingGasSteal)
    {
        _gasStealFinished = true;
    }
    
	// if we know where the enemy region is and where our scout is
	if (_workerScout && enemyBaseLocation)
	{
        int scoutDistanceToEnemy = MapTools::Instance().getGroundDistance(_workerScout->getPosition(), enemyBaseLocation->getPosition());
        bool scoutInRangeOfenemy = scoutDistanceToEnemy <= scoutDistanceThreshold;
        
        // we only care if the scout is under attack within the enemy region
        // this ignores if their scout worker attacks it on the way to their base
        if (scoutHP < _previousScoutHP)
        {
	        _scoutUnderAttack = true;
        }

        if (!_workerScout->isUnderAttack() && !enemyWorkerInRadius())
        {
	        _scoutUnderAttack = false;
        }

		// if the scout is in the enemy region
		if (scoutInRangeOfenemy)
		{
			// get the closest enemy worker
			BWAPI::Unit closestWorker = closestEnemyWorker();

			// if the worker scout is not under attack
			if (!_scoutUnderAttack)
			{
				// if there is a worker nearby, harass it
				if (Config::Strategy::ScoutHarassEnemy && (!Config::Strategy::GasStealWithScout || _gasStealFinished) && closestWorker && (_workerScout->getDistance(closestWorker) < 800))
				{
                    _scoutStatus = "Harass enemy worker";
                    _currentRegionVertexIndex = -1;
					Micro::SmartAttackUnit(_workerScout, closestWorker);
				}
				// otherwise keep moving to the enemy region
				else
				{
                    _scoutStatus = "Following perimeter";
                    followPerimeter();  
                }
				
			}
			// if the worker scout is under attack
			else
			{
                _scoutStatus = "Under attack inside, fleeing";
                followPerimeter();
			}
		}
		// if the scout is not in the enemy region
		else if (_scoutUnderAttack)
		{
            _scoutStatus = "Under attack inside, fleeing";

            followPerimeter();
		}
		else
		{
            _scoutStatus = "Enemy region known, going there";

			// move to the enemy region
			followPerimeter();
        }
		
	}

	// for each start location in the level
	if (!enemyBaseLocation)
	{
        _scoutStatus = "Enemy base unknown, exploring";

		for (BWTA::BaseLocation * startLocation : BWTA::getStartLocations()) 
		{
			// if we haven't explored it yet
			if (!BWAPI::Broodwar->isExplored(startLocation->getTilePosition())) 
			{
				// assign a zergling to go scout it
				Micro::SmartMove(_workerScout, BWAPI::Position(startLocation->getTilePosition()));			
				return;
			}
		}
	}

    _previousScoutHP = scoutHP;
}
Пример #7
0
void CombatCommander::updateDefenseSquads() 
{
	if (_combatUnits.empty() || BWAPI::Broodwar->self()->allUnitCount(BWAPI::UnitTypes::Terran_Science_Vessel) == 1)
    { 
        return; 
    }
    
    BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
    BWTA::Region * enemyRegion = nullptr;
    if (enemyBaseLocation)
    {
        enemyRegion = BWTA::getRegion(enemyBaseLocation->getPosition());
    }

	// for each of our occupied regions
	for (BWTA::Region * myRegion : InformationManager::Instance().getOccupiedRegions(BWAPI::Broodwar->self()))
	{
        // don't defend inside the enemy region, this will end badly when we are stealing gas
        if (myRegion == enemyRegion)
        {
            continue;
        }

		BWAPI::Position regionCenter = myRegion->getCenter();
		if (!regionCenter.isValid())
		{
			continue;
		}

		// start off assuming all enemy units in region are just workers
		int numDefendersPerEnemyUnit = 2;

		// all of the enemy units in this region
		BWAPI::Unitset enemyUnitsInRegion;
        for (auto & unit : BWAPI::Broodwar->enemy()->getUnits())
        {
            // if it's an overlord, don't worry about it for defense, we don't care what they see
            if (unit->getType() == BWAPI::UnitTypes::Zerg_Overlord)
            {
                continue;
            }

            if (BWTA::getRegion(BWAPI::TilePosition(unit->getPosition())) == myRegion)
            {
                enemyUnitsInRegion.insert(unit);
            }
        }

        // we can ignore the first enemy worker in our region since we assume it is a scout
        for (auto & unit : enemyUnitsInRegion)
        {
            if (unit->getType().isWorker())
            {
                enemyUnitsInRegion.erase(unit);
                break;
            }
        }

        int numEnemyFlyingInRegion = std::count_if(enemyUnitsInRegion.begin(), enemyUnitsInRegion.end(), [](BWAPI::Unit u) { return u->isFlying(); });
        int numEnemyGroundInRegion = std::count_if(enemyUnitsInRegion.begin(), enemyUnitsInRegion.end(), [](BWAPI::Unit u) { return !u->isFlying(); });

        std::stringstream squadName;
        squadName << "Base Defense " << regionCenter.x << " " << regionCenter.y; 
        
        // if there's nothing in this region to worry about
        if (enemyUnitsInRegion.empty())
        {
            // if a defense squad for this region exists, remove it
            if (_squadData.squadExists(squadName.str()))
            {
                _squadData.getSquad(squadName.str()).clear();
            }
            
            // and return, nothing to defend here
            continue;
        }
        else 
        {
            // if we don't have a squad assigned to this region already, create one
            if (!_squadData.squadExists(squadName.str()))
            {
                SquadOrder defendRegion(SquadOrderTypes::Defend, regionCenter, 32 * 25, "Defend Region!");
                _squadData.addSquad(squadName.str(), Squad(squadName.str(), defendRegion, BaseDefensePriority));
            }
        }

        // assign units to the squad
        if (_squadData.squadExists(squadName.str()))
        {
            Squad & defenseSquad = _squadData.getSquad(squadName.str());

            // figure out how many units we need on defense
	        int flyingDefendersNeeded = numDefendersPerEnemyUnit * numEnemyFlyingInRegion;
	        int groundDefensersNeeded = numDefendersPerEnemyUnit * numEnemyGroundInRegion;

            updateDefenseSquadUnits(defenseSquad, flyingDefendersNeeded, groundDefensersNeeded);
        }
        else
        {
            UAB_ASSERT_WARNING(false, "Squad should have existed: %s", squadName.str().c_str());
        }
	}

    // for each of our defense squads, if there aren't any enemy units near the position, remove the squad
    std::set<std::string> uselessDefenseSquads;
    for (const auto & kv : _squadData.getSquads())
    {
        const Squad & squad = kv.second;
        const SquadOrder & order = squad.getSquadOrder();

        if (order.getType() != SquadOrderTypes::Defend)
        {
            continue;
        }

        bool enemyUnitInRange = false;
        for (auto & unit : BWAPI::Broodwar->enemy()->getUnits())
        {
            if (unit->getPosition().getDistance(order.getPosition()) < order.getRadius())
            {
                enemyUnitInRange = true;
                break;
            }
        }

        if (!enemyUnitInRange)
        {
            _squadData.getSquad(squad.getName()).clear();
        }
    }
}
void ScoutManager::moveScouts()
{
	if (!workerScout || !workerScout->exists() || !workerScout->getPosition().isValid() || !(workerScout->getHitPoints() > 0))
	{
		return;
	}

	// get the enemy base location, if we have one
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

	// determine the region that the enemy is in
	BWTA::Region * enemyRegion = enemyBaseLocation ? enemyBaseLocation->getRegion() : NULL;

	// determine the region the scout is in
	BWAPI::TilePosition scoutTile(workerScout->getPosition());
	BWTA::Region * scoutRegion = scoutTile.isValid() ? BWTA::getRegion(scoutTile) : NULL;

	// we only care if the scout is under attack within the enemy region
	// this ignores if their scout worker attacks it on the way to their base
	if (workerScout->isUnderAttack() && (scoutRegion == enemyRegion))
	{
		scoutUnderAttack = true;
	}

	if (!workerScout->isUnderAttack() && !enemyWorkerInRadius())
	{
		scoutUnderAttack = false;
	}

	// if we know where the enemy region is and where our scout is
	if (enemyRegion && scoutRegion)
	{
		// if the scout is in the enemy region
		if (scoutRegion == enemyRegion)
		{
			std::vector<GroundThreat> groundThreats;
			fillGroundThreats(groundThreats, workerScout->getPosition());

			// get the closest enemy worker
			BWAPI::UnitInterface* closestWorker = closestEnemyWorker();

			// if the worker scout is not under attack
			if (!scoutUnderAttack)
			{
				// if there is a worker nearby, harass it
				if (closestWorker && (workerScout->getDistance(closestWorker) < 800))
				{
					smartAttack(workerScout, closestWorker);
				}
				// otherwise keep moving to the enemy region
				else
				{
					// move to the enemy region
					smartMove(workerScout, enemyBaseLocation->getPosition());
					BWAPI::Broodwar->drawLineMap(workerScout->getPosition().x, workerScout->getPosition().y, 
						enemyBaseLocation->getPosition().x, enemyBaseLocation->getPosition().y,
						BWAPI::Colors::Yellow);
				}
				
			}
			// if the worker scout is under attack
			else
			{
				BWAPI::Position fleeTo = calcFleePosition(groundThreats, NULL);
				if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawCircleMap(fleeTo.x, fleeTo.y, 10, BWAPI::Colors::Red);

				for (BWAPI::UnitInterface* unit : BWAPI::Broodwar->getUnitsInRadius(fleeTo, 10))
				{
					if (Options::Debug::DRAW_UALBERTABOT_DEBUG) BWAPI::Broodwar->drawCircleMap(unit->getPosition().x, unit->getPosition().y, 5, BWAPI::Colors::Cyan, true);
				}

				smartMove(workerScout, fleeTo);
			}
		}
		// if the scout is not in the enemy region
		else if (scoutUnderAttack)
		{
			smartMove(workerScout, BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation()));
		}
		else
		{
			// move to the enemy region
			smartMove(workerScout, enemyBaseLocation->getPosition());	
		}
		
	}

	// for each start location in the level
	if (!enemyRegion)
	{
		for (BWTA::BaseLocation * startLocation : BWTA::getStartLocations()) 
		{
			// if we haven't explored it yet
			if (!BWAPI::Broodwar->isExplored(startLocation->getTilePosition())) 
			{
				// assign a zergling to go scout it
				smartMove(workerScout, BWAPI::Position(startLocation->getTilePosition()));			
				return;
			}
		}
	}
}
Пример #9
0
  void ScoutManager::updateScoutAssignments()
  {
    // Remove scout positions if the enemy is not there.
    for ( std::map< BWAPI::Unit, ScoutData >::iterator s = m_scouts.begin(); s != m_scouts.end(); s++ )
    {
      if ( s->second.m_mode == ScoutData::Searching
        && s->first->getPosition().getDistance( s->second.m_target->getPosition() ) < s->first->getType().sightRange() )
      {
        bool empty = true;
        for ( int x = s->second.m_target->getTilePosition().x; x < s->second.m_target->getTilePosition().x + 4; x++ )
        {
          for ( int y = s->second.m_target->getTilePosition().y; y < s->second.m_target->getTilePosition().y + 3; y++ )
          {
            for( BWAPI::Unit u : BWAPI::Broodwar->getUnitsOnTile( x, y ) )
            {
              if ( u->getType().isResourceDepot() )
              {
                empty = false;
                break;
              }
            }
            if ( !empty ) break;
          }
          if ( !empty ) break;
        }
        if ( empty )
        {
          m_informationManager->setBaseEmpty( s->second.m_target );
        }
        BWTA::BaseLocation* exploredBaseLocation = s->second.m_target;
        m_baseLocationsToScout.remove( exploredBaseLocation );
        
        m_baseLocationsExplored.insert( exploredBaseLocation );
        s->second.m_mode = ScoutData::Idle;
        if ( m_debugMode )
        {
          BWAPI::Broodwar->printf( "Sucessfully scouted ( %d, %d )", exploredBaseLocation->getPosition().x, exploredBaseLocation->getPosition().y );
        }
      }
    }

    // Set scouts to scout.
    if ( m_baseLocationsToScout.size() > 0 ) // are there still positions to scout?
    {
      for ( std::map< BWAPI::Unit, ScoutData >::iterator s = m_scouts.begin(); s != m_scouts.end(); s++ )
      {
        if ( s->second.m_mode == ScoutData::Idle )
        {
          double minDist = 100000000;
          BWTA::BaseLocation* target = NULL;
          for( BWTA::BaseLocation* bl : m_baseLocationsToScout )
          {
            double distance = s->first->getPosition().getDistance( bl->getPosition() );
            if ( distance < minDist )
            {
              minDist = distance;
              target = bl;
            }
          }
          if ( target != NULL )
          {
            s->second.m_mode = ScoutData::Searching;
            s->first->rightClick( target->getPosition() );
            s->second.m_target = target;
            m_baseLocationsToScout.remove( target );
            if ( m_debugMode )
            {
              BWAPI::Broodwar->printf( "Scouting ( %d, %d )", target->getPosition().x, target->getPosition().y );
            }
          }
        }
      }
    }

  }
Пример #10
0
void ScoutManager::moveScouts()
{
	if (!_workerScout || !_workerScout->exists() || !(_workerScout->getHitPoints() > 0))
	{
		return;
	}
	

    int scoutHP = _workerScout->getHitPoints() + _workerScout->getShields();
    
    gasSteal();

	// get the enemy base location, if we have one
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

    int scoutDistanceThreshold = 30;

    if (_workerScout->isCarryingGas())
    {
        BWAPI::Broodwar->drawCircleMap(_workerScout->getPosition(), 10, BWAPI::Colors::Purple, true);
    }

    // if we initiated a gas steal and the worker isn't idle, 
    bool finishedConstructingGasSteal = _workerScout->isIdle() || _workerScout->isCarryingGas();
    if (!_gasStealFinished && _didGasSteal && !finishedConstructingGasSteal)
    {
        return;
    }
    // check to see if the gas steal is completed
    else if (_didGasSteal && finishedConstructingGasSteal)
    {
        _gasStealFinished = true;
    }


	for (auto & iter : explore_val)
	{
		int x1 = _workerScout->getPosition().x;
		int y1 = _workerScout->getPosition().y;
		int x2 = (iter.first)->getPosition().x;
		int y2 = (iter.first)->getPosition().y;

		double distance = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) + 0.0);
		if (distance > 800)
		{
			continue;
		}

		if (enemyBaseLocation != nullptr && iter.first == enemyBaseLocation)
		{
			patrol_counter++;
			if (patrol_counter >= 480)
			{
				patrol_counter = 0;
				iter.second = 0;
			}
		}
		else if (distance <= 100)
		{
			iter.second = 0;
		}
	}

	BWAPI::Position scout_pos = _workerScout->getPosition();
	double cur_dis = scout_pos.getDistance(next_pos);

	BWAPI::Broodwar->drawTextScreen(200, 280, "Next position : %d %d", next_pos.x, next_pos.y);
	BWAPI::Broodwar->drawTextScreen(200, 290, "distance to next position:\t%.2lf", cur_dis);

	if (cur_dis > 150)
	{
		Micro::SmartMove(_workerScout, next_pos);
		return;
	}

	// if we know where the enemy region is and where our scout is
	if (_workerScout && enemyBaseLocation)
	{
		//lpx
		int max_prior = 0;
		for (auto iter : explore_val)
		{
			if (iter.second > max_prior)
			{
				max_prior = iter.second;
				pass_by = iter.first;
			}
		}
		if (pass_by != enemyBaseLocation)
		{
			next_pos = BWAPI::Position(pass_by->getTilePosition());
			Micro::SmartMove(_workerScout, next_pos);
			_scoutStatus = "Found higher priority than enemy base, first going there";
			return;
		}

        int scoutDistanceToEnemy = MapTools::Instance().getGroundDistance(_workerScout->getPosition(), enemyBaseLocation->getPosition());
        bool scoutInRangeOfenemy = scoutDistanceToEnemy <= scoutDistanceThreshold;
        
        // we only care if the scout is under attack within the enemy region
        // this ignores if their scout worker attacks it on the way to their base
        if (scoutHP < _previousScoutHP)
        {
	        _scoutUnderAttack = true;
        }

        if (!_workerScout->isUnderAttack() && !enemyWorkerInRadius())
        {
	        _scoutUnderAttack = false;
        }

		// if the scout is in the enemy region
		if (scoutInRangeOfenemy)
		{
			// get the closest enemy worker
			BWAPI::Unit closestWorker = closestEnemyWorker();

			// if the worker scout is not under attack
			if (!_scoutUnderAttack)
			{
				/*
				// if there is a worker nearby, harass it
				if (Config::Strategy::ScoutHarassEnemy && (!Config::Strategy::GasStealWithScout || _gasStealFinished) && closestWorker && (_workerScout->getDistance(closestWorker) < 800))
				{
                    _scoutStatus = "Harass enemy worker";
                    _currentRegionVertexIndex = -1;
					Micro::SmartAttackUnit(_workerScout, closestWorker);
				}
				// otherwise keep moving to the enemy region
				*/
				_scoutStatus = "Following perimeter";
                followPerimeter();  
                
			}
			// if the worker scout is under attack
			else
			{
                _scoutStatus = "Under attack inside, fleeing";
                followPerimeter();
			}
		}
		// if the scout is not in the enemy region
		else if (_scoutUnderAttack)
		{
            _scoutStatus = "Under attack inside, fleeing";

            followPerimeter();
		}
		else
		{
            _scoutStatus = "Enemy region known, going there";

			// move to the enemy region
			followPerimeter();
        }
		
	}

	// for each start location in the level
	if (!enemyBaseLocation)
	{
        _scoutStatus = "Enemy base unknown, exploring";

		for (BWTA::BaseLocation * startLocation : BWTA::getStartLocations()) 
		{
			// if we haven't explored it yet
			if (!BWAPI::Broodwar->isExplored(startLocation->getTilePosition())) 
			{
				// assign a zergling to go scout it
				next_pos = BWAPI::Position(startLocation->getPosition());
				Micro::SmartMove(_workerScout, BWAPI::Position(startLocation->getTilePosition()));			
				return;
			}
		}
	}

    _previousScoutHP = scoutHP;
}