Пример #1
0
void ScoutManager::drawScoutInformation(int x, int y)
{
    if (!Config::Debug::DrawScoutInfo)
    {
        return;
    }

	BWAPI::Broodwar->drawTextScreen(x, y - 10, "Enemy base timer == %d", patrol_counter);

    BWAPI::Broodwar->drawTextScreen(x, y, "ScoutInfo: %s", _scoutStatus.c_str());

	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
	double distance = 0.0;
	if (_workerScout && _workerScout->exists() && enemyBaseLocation)
	{
		BWAPI::Position tmp = BWAPI::Position(enemyBaseLocation->getTilePosition());
		int x1 = _workerScout->getPosition().x;
		int y1 = _workerScout->getPosition().y;

		int x2 = tmp.x;
		int y2 = tmp.y;

		distance = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) + 0.0);
	}
	 
    BWAPI::Broodwar->drawTextScreen(x, y+10, "Distance to enemy base: %.2lf", distance);
    for (size_t i(0); i < _enemyRegionVertices.size(); ++i)
    {
        BWAPI::Broodwar->drawCircleMap(_enemyRegionVertices[i], 4, BWAPI::Colors::Green, false);
        BWAPI::Broodwar->drawTextMap(_enemyRegionVertices[i], "%d", i);
    }
}
Пример #2
0
BWAPI::TilePosition getNextExpansionLocation(TilePosition currentExpo)
{
	//remove the current expo from the list
	//loop through expos and find the nearest one
	std::set<BWTA::BaseLocation*> bases;

	for (auto &u : allBases)
	{
		//make sure we delete the current expansion
		if (u->getTilePosition() == currentExpo)
		{
			allBases.erase(u);
		}
	}
	BWTA::BaseLocation *ret = *allBases.begin();

	int minDistance = currentExpo.getApproxDistance(ret->getTilePosition());

	//make sure we dont accidently find current expansion
	for (auto &u : allBases)
	{
		int tempDistance = currentExpo.getApproxDistance(u->getTilePosition());
		if (tempDistance < minDistance && tempDistance > 10)
		{
			//found a closer base
			minDistance = tempDistance;
			ret = u;
		}
	}
	return ret->getTilePosition();
}
Пример #3
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();
}
Пример #4
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 building a bunker for strategy "Terran_Custom", return one location near an attacked unit
	if ((b.type == BWAPI::UnitTypes::Terran_Bunker) && (Config::Strategy::StrategyName == "Terran_Custom"))
	{
		for (auto & unit : BWAPI::Broodwar->self()->getUnits())
		{
			if (unit->isUnderAttack())
			{
				return BuildingPlacer::Instance().getBuildLocationNear(b, 1, false);
				break;
			}
		}
	}
	
    if (b.type.isRefinery())
    {
        return BuildingPlacer::Instance().getRefineryPosition();
    }

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

        return tile;
    }

    // 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);
}
BWAPI::Unit ScoutManager::getEnemyGeyser()
{
	BWAPI::Unit geyser = nullptr;
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

	for (auto & unit : enemyBaseLocation->getGeysers())
	{
		geyser = unit;
	}

	return geyser;
}
BWAPI::UnitInterface* ScoutManager::getEnemyGeyser()
{
	BWAPI::UnitInterface* geyser = NULL;
	BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());

	for (BWAPI::UnitInterface* unit : enemyBaseLocation->getGeysers())
	{
		geyser = unit;
	}

	return geyser;
}
Пример #8
0
void ProbeUnit::check()
{
	if (backUpMineral == NULL || !backUpMineral->exists())
	{
		if (Broodwar->getFrameCount() < 10*24*60)
		{
			BWTA::BaseLocation* b = BWTA::getStartLocation(Broodwar->self());
			if (b != NULL && !b->getMinerals().empty())
				backUpMineral = *(b->getMinerals().begin());
			if (backUpMineral == NULL || !backUpMineral->exists())
				backUpMineral = NULL;
		}
	}
}
Пример #9
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 );
   }
 }
Пример #10
0
BWTA::BaseLocation* BaseManager::expand(int priority)
{
	BWTA::BaseLocation* location = NULL;
	BWTA::BaseLocation* locationWithoutGas = NULL;

	double minDist=-1;
	BWTA::BaseLocation* home = BWTA::getStartLocation(BWAPI::Broodwar->self());

	std::set<BWTA::BaseLocation*>::const_iterator i;
	for(i = BWTA::getBaseLocations().begin(); i != BWTA::getBaseLocations().end(); i++)
	{
		BWTA::BaseLocation *baseLocation = (*i);

		if (baseLocation->isIsland())
		{
			continue;
		}

		double dist = home->getGroundDistance(baseLocation);
		if (dist > 0 && getBase(baseLocation) == NULL)
		{
			if (minDist == -1 || dist < minDist)
			{
				if (baseLocation->isMineralOnly())
				{
					locationWithoutGas = baseLocation;
				}
				else
				{
					location = baseLocation;
					minDist = dist;
				}
			}
		}
	}

	if (location == NULL && locationWithoutGas != NULL)
	{
		BWAPI::Broodwar->printf("Expanding to location without gas.");

		location = locationWithoutGas;
	}

	return expand(location, priority);
}
Пример #11
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);
}
Пример #12
0
bool WorkerManager::isGasStealRefinery(BWAPI::Unit unit)
{
    BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
    if (!enemyBaseLocation)
    {
        return false;
    }
    
    if (enemyBaseLocation->getGeysers().empty())
    {
        return false;
    }
    
	for (auto & u : enemyBaseLocation->getGeysers())
	{
        if (unit->getTilePosition() == u->getTilePosition())
        {
            return true;
        }
	}

    return false;
}
Пример #13
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");
	}
}
Пример #14
0
BWAPI::TilePosition MapTools::getNextExpansion(BWAPI::Player player)
{
    BWTA::BaseLocation * closestBase = nullptr;
    double minDistance = 100000;

    BWAPI::TilePosition homeTile = player->getStartLocation();

    // for each base location
    for (BWTA::BaseLocation * base : BWTA::getBaseLocations())
    {
        // if the base has gas
        if (!base->isMineralOnly() && !(base == BWTA::getStartLocation(player)))
        {
            // get the tile position of the base
            BWAPI::TilePosition tile = base->getTilePosition();
            bool buildingInTheWay = false;

            for (int x = 0; x < BWAPI::Broodwar->self()->getRace().getCenter().tileWidth(); ++x)
            {
                for (int y = 0; y < BWAPI::Broodwar->self()->getRace().getCenter().tileHeight(); ++y)
                {
                    BWAPI::TilePosition tp(tile.x + x, tile.y + y);

                    for (auto & unit : BWAPI::Broodwar->getUnitsOnTile(tp))
                    {
                        if (unit->getType().isBuilding() && !unit->isFlying())
                        {
                            buildingInTheWay = true;
                            break;
                        }
                    }
                }
            }
            
            if (buildingInTheWay)
            {
                continue;
            }

            // the base's distance from our main nexus
            BWAPI::Position myBasePosition(player->getStartLocation());
            BWAPI::Position thisTile = BWAPI::Position(tile);
            double distanceFromHome = MapTools::Instance().getGroundDistance(thisTile,myBasePosition);

            // if it is not connected, continue
            if (!BWTA::isConnected(homeTile,tile) || distanceFromHome < 0)
            {
                continue;
            }

            if (!closestBase || distanceFromHome < minDistance)
            {
                closestBase = base;
                minDistance = distanceFromHome;
            }
        }

    }

    if (closestBase)
    {
        return closestBase->getTilePosition();
    }
    else
    {
        return BWAPI::TilePositions::None;
    }
}
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;
}
void ScoutManager::calculateEnemyRegionVertices()
{
    BWTA::BaseLocation * enemyBaseLocation = InformationManager::Instance().getMainBaseLocation(BWAPI::Broodwar->enemy());
    //UAB_ASSERT_WARNING(enemyBaseLocation, "We should have an enemy base location if we are fleeing");

    if (!enemyBaseLocation)
    {
        return;
    }

    BWTA::Region * enemyRegion = enemyBaseLocation->getRegion();
    //UAB_ASSERT_WARNING(enemyRegion, "We should have an enemy region if we are fleeing");

    if (!enemyRegion)
    {
        return;
    }

    const BWAPI::Position basePosition = BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation());
    const std::vector<BWAPI::TilePosition> & closestTobase = MapTools::Instance().getClosestTilesTo(basePosition);

    std::set<BWAPI::Position> unsortedVertices;

    // check each tile position
    for (size_t i(0); i < closestTobase.size(); ++i)
    {
        const BWAPI::TilePosition & tp = closestTobase[i];

        if (BWTA::getRegion(tp) != enemyRegion)
        {
            continue;
        }

        // a tile is 'surrounded' if
        // 1) in all 4 directions there's a tile position in the current region
        // 2) in all 4 directions there's a buildable tile
        bool surrounded = true;
        if (BWTA::getRegion(BWAPI::TilePosition(tp.x+1, tp.y)) != enemyRegion || !BWAPI::Broodwar->isBuildable(BWAPI::TilePosition(tp.x+1, tp.y))
            || BWTA::getRegion(BWAPI::TilePosition(tp.x, tp.y+1)) != enemyRegion || !BWAPI::Broodwar->isBuildable(BWAPI::TilePosition(tp.x, tp.y+1))
            || BWTA::getRegion(BWAPI::TilePosition(tp.x-1, tp.y)) != enemyRegion || !BWAPI::Broodwar->isBuildable(BWAPI::TilePosition(tp.x-1, tp.y))
            || BWTA::getRegion(BWAPI::TilePosition(tp.x, tp.y-1)) != enemyRegion || !BWAPI::Broodwar->isBuildable(BWAPI::TilePosition(tp.x, tp.y -1))) 
        { 
            surrounded = false; 
        }
        
        // push the tiles that aren't surrounded
        if (!surrounded && BWAPI::Broodwar->isBuildable(tp))
        {
            if (Config::Debug::DrawScoutInfo)
            {
                int x1 = tp.x * 32 + 2;
                int y1 = tp.y * 32 + 2;
                int x2 = (tp.x+1) * 32 - 2;
                int y2 = (tp.y+1) * 32 - 2;
        
                BWAPI::Broodwar->drawTextMap(x1+3, y1+2, "%d", MapTools::Instance().getGroundDistance(BWAPI::Position(tp), basePosition));
                BWAPI::Broodwar->drawBoxMap(x1, y1, x2, y2, BWAPI::Colors::Green, false);
            }
            
            unsortedVertices.insert(BWAPI::Position(tp) + BWAPI::Position(16, 16));
        }
    }


    std::vector<BWAPI::Position> sortedVertices;
    BWAPI::Position current = *unsortedVertices.begin();

    _enemyRegionVertices.push_back(current);
    unsortedVertices.erase(current);

    // while we still have unsorted vertices left, find the closest one remaining to current
    while (!unsortedVertices.empty())
    {
        double bestDist = 1000000;
        BWAPI::Position bestPos;

        for (const BWAPI::Position & pos : unsortedVertices)
        {
            double dist = pos.getDistance(current);

            if (dist < bestDist)
            {
                bestDist = dist;
                bestPos = pos;
            }
        }

        current = bestPos;
        sortedVertices.push_back(bestPos);
        unsortedVertices.erase(bestPos);
    }

    // let's close loops on a threshold, eliminating death grooves
    int distanceThreshold = 100;

    while (true)
    {
        // find the largest index difference whose distance is less than the threshold
        int maxFarthest = 0;
        int maxFarthestStart = 0;
        int maxFarthestEnd = 0;

        // for each starting vertex
        for (int i(0); i < (int)sortedVertices.size(); ++i)
        {
            int farthest = 0;
            int farthestIndex = 0;

            // only test half way around because we'll find the other one on the way back
            for (size_t j(1); j < sortedVertices.size()/2; ++j)
            {
                int jindex = (i + j) % sortedVertices.size();
            
                if (sortedVertices[i].getDistance(sortedVertices[jindex]) < distanceThreshold)
                {
                    farthest = j;
                    farthestIndex = jindex;
                }
            }

            if (farthest > maxFarthest)
            {
                maxFarthest = farthest;
                maxFarthestStart = i;
                maxFarthestEnd = farthestIndex;
            }
        }
        
        // stop when we have no long chains within the threshold
        if (maxFarthest < 4)
        {
            break;
        }

        double dist = sortedVertices[maxFarthestStart].getDistance(sortedVertices[maxFarthestEnd]);

        std::vector<BWAPI::Position> temp;

        for (size_t s(maxFarthestEnd); s != maxFarthestStart; s = (s+1) % sortedVertices.size())
        {
            temp.push_back(sortedVertices[s]);
        }

        sortedVertices = temp;
    }

    _enemyRegionVertices = sortedVertices;
}
Пример #17
0
// STEP 6: CHECK FOR COMPLETED BUILDINGS
void BuildingManager::checkForCompletedBuildings()
{
	std::vector<Building> toRemove;

	// for each of our buildings under construction
	for (auto & b : _buildings)
	{
		if (b.status != BuildingStatus::UnderConstruction)
		{
			continue;
		}

		// if the unit has completed
		if (b.buildingUnit->isCompleted())
		{
			if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg)
			{
				if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Creep_Colony)
				{
					//b.buildingUnit->upgrade(b.buildingUnit->getUpgrade());
					//b.buildingUnit->buildAddon(BWAPI::UnitTypes::Zerg_Sunken_Colony);

					// MAKE SUNKEN
					//b.buildingUnit->morph(BWAPI::UnitTypes::Zerg_Sunken_Colony);
					MetaType type(BWAPI::UnitTypes::Zerg_Sunken_Colony);
					//ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);

				}

				if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery)
				{
					createdHatchery = true;


				}
				/*
				if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery)
				{
				for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits())
				{
				if (!madeFirstSunken && p->getType().isWorker() && p->getPosition() == firstHatcheryPosition)
				{
				//BWAPI::Position tempPosition;
				//tempPosition.x = b.finalPosition.x + 3;
				//tempPosition.y = b.finalPosition.y + 3;
				MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony);
				ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);
				/*
				BWAPI::TilePosition sunkPos = getSunkenPosition();
				createdSunkenSet.insert(sunkPos);
				createdSunkenVector.push_back(sunkPos);
				createdBuilding.insert(sunkPos);
				p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos);
				madeFirstSunken = true;
				BWAPI::TilePosition sunkPos2 = getSunkenPosition();
				createdSunkenSet.insert(sunkPos2);
				createdSunkenVector.push_back(sunkPos2);
				createdBuilding.insert(sunkPos2);
				p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos2);
				//b.builderUnit->build(b.type, b.finalPosition);

				break;

				//candidateProducers.insert(p);
				}
				}
				}
				*/

			}
			// if we are terran, give the worker back to worker manager
			if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Terran)
			{
				if (b.isGasSteal)
				{
					ScoutManager::Instance().setWorkerScout(b.builderUnit);
				}
				// otherwise tell the worker manager we're finished with this unit
				else
				{
					WorkerManager::Instance().finishedWithWorker(b.builderUnit);
				}
			}



			// remove this unit from the under construction vector
			toRemove.push_back(b);
		}
		else
		{
			if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1050 &&  !transferredDrones)
			{


				//BWAPI::Broodwar->printf("Send Drone");
				//BWAPI::Unitset candidateProducers;
				BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony;
				Building z(sunk, createdHatcheriesVector[0]);
				//BWAPI::Unit workerToAssign = WorkerManager::Instance().getMoveWorker(BWAPI::Position(createdHatcheriesVector[0]));
				//BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getMoveWorker(BWAPI::Position(createdHatcheriesVector[0]));
				//WorkerManager::Instance().setMoveWorker(0, 0, BWAPI::Position(createdHatcheriesVector[0]));
				//WorkerManager::Instance().setMoveWorker(0, 0, BWAPI::Position(createdHatcheriesVector[0]));
				//_reservedMinerals += 75;


				BWAPI::Unit workerToAssign = WorkerManager::Instance().getBuilder(z);
				BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getBuilder(z);

				//WorkerData m;
				//m.setWorkerJob(workerToAssign, WorkerData::Minerals, b.type);
				/*
				for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits())
				{
				WorkerData k;

				WorkerData::WorkerJob j = k.getWorkerJob(p);
				if (p->getType().isWorker() && j != WorkerData::Scout)
				{
				*/

				const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations();
				BWTA::BaseLocation *myLocation;

				for (BWTA::BaseLocation *p : locations) {
					BWAPI::TilePosition z = p->getTilePosition();
					if (z == createdHatcheriesVector[0]){
						// This is the BWTA::Location of the first hatchery.
						myLocation = p;
					}
				}
				// Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set)
				const BWAPI::Unitset mineralSet = myLocation->getMinerals();

				BWAPI::Unit myMineral;
				for (BWAPI::Unit p : mineralSet)
				{
					myMineral = p;
					// Calculate the difference between LeftMostMineralPatch.x - ExpansionHatchery.x and store it in theX
					//theX = p->getTilePosition().x - hatchPosition.x;
					// Calculate the difference between LeftMostMineralPatch.y - ExpansionHatchery.y and store it in theY
					//theY = p->getTilePosition().y - hatchPosition.y;
					break;
				}



				workerToAssign->gather(myMineral);
				workerToAssign2->gather(myMineral);
				sunkenUnit = workerToAssign;
				sunkenUnit2 = workerToAssign2;
				//sunkenID = workerToAssign->getID();


			
				transferredDrones = true;

			}

			if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1225 && !sentFirstDroneForSunken)
			{
				MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony);
				ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);
						//sunkenID2 = workerToAssign2->getID();
						//BWAPI::TilePosition tempPosition;
						//tempPosition.x = b.finalPosition.x+4;
						//tempPosition.y = b.finalPosition.y+4;
						//Micro::SmartMove(p, BWAPI::Position(tempPosition));
						//Micro::SmartMove(p, BWAPI::Position(tempPosition));
						//p->move(BWAPI::Position(tempPosition));
						//p->move(BWAPI::Position(tempPosition));
						//break;
						//candidateProducers.insert(p);
					
				//MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony);
				//ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);
				sentFirstDroneForSunken = true;
			}

		}
	}

	removeBuildings(toRemove);
}
Пример #18
0
void BasicAIModule::onStart()
{
  Broodwar->enableFlag( Flag::UserInput );
  BWTA::readMap();
  BWTA::analyze();
  BWSAL::resetLog();

  m_informationManager = InformationManager::create();
  m_borderManager = BorderManager::create( m_informationManager );
  m_baseManager = BaseManager::create( m_borderManager );
  m_buildingPlacer = new BFSBuildingPlacer();
  m_reservedMap = ReservedMap::create();
  m_unitArbitrator = new UnitArbitrator();
  m_unitGroupManager = UnitGroupManager::create();
  m_buildUnitManager = BuildUnitManager::create();
  m_buildEventTimeline = BuildEventTimeline::create( m_buildUnitManager );
  m_taskScheduler = TaskScheduler::create( m_buildEventTimeline, m_buildUnitManager );
  m_taskExecutor = TaskExecutor::create( m_unitArbitrator, m_buildEventTimeline, m_reservedMap, m_buildingPlacer );
  m_workerManager = WorkerManager::create( m_unitArbitrator, m_baseManager );
  m_scoutManager = ScoutManager::create( m_unitArbitrator, m_informationManager );
  m_defenseManager = DefenseManager::create( m_unitArbitrator, m_borderManager );
  m_buildOrderManager = BuildOrderManager::create( m_taskScheduler, m_taskExecutor, m_buildUnitManager );
  m_supplyManager = SupplyManager::create( m_buildOrderManager, m_taskScheduler );
  m_enhancedUI = new EnhancedUI();

  m_buildEventTimeline->initialize();
  m_scoutManager->initialize();

  m_modules.push_back( m_informationManager );
  m_modules.push_back( m_borderManager );
  m_modules.push_back( m_baseManager );
  m_modules.push_back( m_buildEventTimeline );
  m_modules.push_back( m_reservedMap );
  m_modules.push_back( m_unitGroupManager );
  m_modules.push_back( m_buildUnitManager );
  m_modules.push_back( m_taskScheduler );
  m_modules.push_back( m_taskExecutor );
  m_modules.push_back( m_workerManager );
  m_modules.push_back( m_scoutManager );
  m_modules.push_back( m_defenseManager );

  BWAPI::Race race = Broodwar->self()->getRace();
  BWAPI::Race enemyRace = Broodwar->enemy()->getRace();
  double minDist;
  BWTA::BaseLocation* natural = NULL;
  BWTA::BaseLocation* home = BWTA::getStartLocation( Broodwar->self() );
  foreach( BWTA::BaseLocation* bl, BWTA::getBaseLocations() )
  {
    if ( bl != home )
    {
      double dist = home->getGroundDistance( bl );
      if ( dist > 0 )
      {
        if ( natural == NULL || dist < minDist)
        {
          minDist = dist;
          natural = bl;
        }
      }
    }
  }
  int buildID = 1;
  if ( race == Races::Zerg )
  {
    // Send an overlord out if Zerg
    m_scoutManager->setScoutCount( 1 );

    if (buildID == 1)
    {
      //morph 5 lurkers (tests dependency resolver, task scheduler)
      m_buildOrderManager->build( 8, UnitTypes::Zerg_Drone, 90 );
      m_buildOrderManager->buildAdditional( 1, UnitTypes::Zerg_Overlord, 85 );
      m_buildOrderManager->build( 12, UnitTypes::Zerg_Drone, 84 );
      m_buildOrderManager->buildAdditional( 1, UnitTypes::Zerg_Lair, 82);
      m_buildOrderManager->buildAdditional( 5, UnitTypes::Zerg_Lurker, 80);
      m_buildOrderManager->build( 12, UnitTypes::Zerg_Drone, 30 );
    }
    else if (buildID >= 2)
    {
      //12 pool 6 lings (tests larva task scheduler)
      m_buildOrderManager->build( 8, UnitTypes::Zerg_Drone, 90 );
      m_buildOrderManager->buildAdditional( 1, UnitTypes::Zerg_Overlord, 85 );
      m_buildOrderManager->build( 12, UnitTypes::Zerg_Drone, 84 );
      m_buildOrderManager->buildAdditional( 1, UnitTypes::Zerg_Spawning_Pool, 70 );
      m_buildOrderManager->buildAdditional( 3, UnitTypes::Zerg_Zergling, 65 );
      m_buildOrderManager->build( 40, UnitTypes::Zerg_Drone, 62 );
    }
  }
  else if ( race == Races::Terran )
  {
    if (buildID == 1)
    {
      //build 3 comsat stations (tests dependency resolver)
      m_buildOrderManager->build(9,UnitTypes::Terran_SCV,90);
      m_buildOrderManager->build(1,UnitTypes::Terran_Supply_Depot,85);
      m_buildOrderManager->build(20,UnitTypes::Terran_SCV,80);
      m_buildOrderManager->buildAdditional(3,UnitTypes::Terran_Comsat_Station,60);
    }
    else if (buildID == 2)
    {
      //a complex build order
      m_buildOrderManager->build(9,UnitTypes::Terran_SCV,90);
      m_buildOrderManager->build(1,UnitTypes::Terran_Supply_Depot,85);
      m_buildOrderManager->build(20,UnitTypes::Terran_SCV,80);
      m_buildOrderManager->buildAdditional(1,UnitTypes::Terran_Barracks,60);
      m_buildOrderManager->buildAdditional(9,UnitTypes::Terran_Marine,45);
 
      m_buildOrderManager->buildAdditional(1,UnitTypes::Terran_Refinery,42);
      m_buildOrderManager->buildAdditional(1,UnitTypes::Terran_Barracks,40);
      m_buildOrderManager->buildAdditional(1,UnitTypes::Terran_Academy,39);
      m_buildOrderManager->buildAdditional(9,UnitTypes::Terran_Medic,38);


      m_buildOrderManager->research(TechTypes::Stim_Packs,35);
      m_buildOrderManager->research(TechTypes::Tank_Siege_Mode,35);
      m_buildOrderManager->buildAdditional(3,UnitTypes::Terran_Siege_Tank_Tank_Mode,34);
      m_buildOrderManager->buildAdditional(2,UnitTypes::Terran_Science_Vessel,30);
      m_buildOrderManager->research(TechTypes::Irradiate,30);

      m_buildOrderManager->upgrade(1,UpgradeTypes::Terran_Infantry_Weapons,20);
      m_buildOrderManager->build(3,UnitTypes::Terran_Missile_Turret,13);
      m_buildOrderManager->upgrade(3,UpgradeTypes::Terran_Infantry_Weapons,12);
      m_buildOrderManager->upgrade(3,UpgradeTypes::Terran_Infantry_Armor,12);
      m_buildOrderManager->build(1,UnitTypes::Terran_Engineering_Bay,11);
      m_buildOrderManager->buildAdditional(40,UnitTypes::Terran_Marine,10);
      m_buildOrderManager->build(6,UnitTypes::Terran_Barracks,8);
      m_buildOrderManager->build(2,UnitTypes::Terran_Engineering_Bay,7);
      m_buildOrderManager->buildAdditional(10,UnitTypes::Terran_Siege_Tank_Tank_Mode,5);
    }
    else if (buildID >= 3)
    {
      //terran mech - tests task ordering with add-on requiring units
      m_buildOrderManager->build(9,UnitTypes::Terran_SCV,90);
      m_buildOrderManager->build(1,UnitTypes::Terran_Supply_Depot,85);
      m_buildOrderManager->build(20,UnitTypes::Terran_SCV,80);
      m_buildOrderManager->buildAdditional(2,BWAPI::UnitTypes::Terran_Machine_Shop,70);
      m_buildOrderManager->buildAdditional(3,BWAPI::UnitTypes::Terran_Factory,60);
      m_buildOrderManager->research(TechTypes::Spider_Mines,55);
      m_buildOrderManager->research(TechTypes::Tank_Siege_Mode,55);
      m_buildOrderManager->buildAdditional(20,BWAPI::UnitTypes::Terran_Vulture,40);
      m_buildOrderManager->buildAdditional(20,BWAPI::UnitTypes::Terran_Siege_Tank_Tank_Mode,40);
      m_buildOrderManager->upgrade(3,UpgradeTypes::Terran_Vehicle_Weapons,20);
    }
    
  }
  else if (race == Races::Protoss)
  {
    //build 20 carriers - tests dependency resolver
    m_buildOrderManager->build(8,UnitTypes::Protoss_Probe,90);
    m_buildOrderManager->build(1,UnitTypes::Protoss_Pylon,85);
    m_buildOrderManager->build(20,UnitTypes::Protoss_Probe,80);
    m_buildOrderManager->buildAdditional(10,UnitTypes::Protoss_Dragoon,70);
    m_buildOrderManager->buildAdditional(10,UnitTypes::Protoss_Zealot,70);
    m_buildOrderManager->upgrade(1,UpgradeTypes::Singularity_Charge,61);
    m_buildOrderManager->buildAdditional(20,UnitTypes::Protoss_Carrier,60);
  }
  m_drawTasks = true;
  m_drawAssignments = false;
  m_drawResources = true;
  m_drawLarva = Broodwar->self()->getRace() == Races::Zerg;

}
Пример #19
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 );
            }
          }
        }
      }
    }

  }
Пример #20
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;
}
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
      // Make every other base for zerg a macro hatch.
      bool is_macro = false;
	  if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg) {
        int num_mains = UnitUtil::GetAllUnitCount(BWAPI::UnitTypes::Zerg_Hatchery) + UnitUtil::GetAllUnitCount(BWAPI::UnitTypes::Zerg_Lair) + UnitUtil::GetAllUnitCount(BWAPI::UnitTypes::Zerg_Hive);
        if (num_mains % 2 == 1)
          is_macro = true;
      }

	  if (!is_macro || Config::Strategy::StrategyName == "GreedyHydras") {
        BWAPI::TilePosition tile = MapTools::Instance().getNextExpansion();
        return tile;
      }
    }

    if (b.type == BWAPI::UnitTypes::Zerg_Creep_Colony) {
      // Half way between start and choke.
      BWAPI::TilePosition startLocation = BWAPI::Broodwar->self()->getStartLocation();
      BWAPI::TilePosition chokeLocation = BWAPI::TilePosition(BWTA::getNearestChokepoint(startLocation)->getCenter());

      // IS THIS HOW I AVERAGE POINTS? HAHA, LET'S SEE.
      return BWAPI::Broodwar->getBuildLocation(b.type, chokeLocation, 64, true);
    }

    // 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);
}
Пример #22
0
void InformationManager::updateBaseLocationInfo() 
{
	_occupiedRegions[_self].clear();
	_occupiedRegions[_enemy].clear();
		
	// if we haven't found the enemy main base location yet
	if (!_mainBaseLocations[_enemy]) 
	{ 
		// how many start locations have we explored
		int exploredStartLocations = 0;
		bool baseFound = false;

		// an undexplored base location holder
		BWTA::BaseLocation * unexplored = nullptr;

		for (BWTA::BaseLocation * startLocation : BWTA::getStartLocations()) 
		{
			if (isEnemyBuildingInRegion(BWTA::getRegion(startLocation->getTilePosition()))) 
			{
                if (Config::Debug::DrawScoutInfo)
                {
				    BWAPI::Broodwar->printf("Enemy base found by seeing it");
                }

				baseFound = true;
				_mainBaseLocations[_enemy] = startLocation;
				updateOccupiedRegions(BWTA::getRegion(startLocation->getTilePosition()), BWAPI::Broodwar->enemy());
			}

			// if it's explored, increment
			if (BWAPI::Broodwar->isExplored(startLocation->getTilePosition())) 
			{
				exploredStartLocations++;

			// otherwise set the unexplored base
			} 
			else 
			{
				unexplored = startLocation;
			}
		}

		// if we've explored every start location except one, it's the enemy
		if (!baseFound && exploredStartLocations == ((int)BWTA::getStartLocations().size() - 1)) 
		{
            if (Config::Debug::DrawScoutInfo)
            {
                BWAPI::Broodwar->printf("Enemy base found by process of elimination");
            }
			
			_mainBaseLocations[_enemy] = unexplored;
			updateOccupiedRegions(BWTA::getRegion(unexplored->getTilePosition()), BWAPI::Broodwar->enemy());
		}
	// otherwise we do know it, so push it back
	} 
	else 
	{
		updateOccupiedRegions(BWTA::getRegion(_mainBaseLocations[_enemy]->getTilePosition()), BWAPI::Broodwar->enemy());
	}

	// for each enemy unit we know about
	size_t enemyBaseCount = 0;
	size_t enemySunkenCount = 0;
	for (const auto & kv : _unitData[_enemy].getUnits())
	{
		const UnitInfo & ui(kv.second);
		BWAPI::UnitType type = ui.type;

		// if the unit is a building
		if (type.isBuilding()) 
		{
			// update the enemy occupied regions
			updateOccupiedRegions(BWTA::getRegion(BWAPI::TilePosition(ui.lastPosition)), BWAPI::Broodwar->enemy());
		}
		
		if (type.isResourceDepot())
		{
			++enemyBaseCount;
		}

		if (type == BWAPI::UnitTypes::Zerg_Sunken_Colony){
			++enemySunkenCount;
		}

	}
	
	if (_mainBaseLocations[_enemy]){
		if (BWAPI::Broodwar->isExplored(_mainBaseLocations[_enemy]->getTilePosition()) && !_scoutTimer) _scoutTimer = BWAPI::Broodwar->getFrameCount() + 100;
	}
	if (enemyBaseCount > 1 && BWAPI::Broodwar->getFrameCount() < _scoutTimer){
		_enemyExpand = true;
	}


	if (enemySunkenCount > 1){
		Config::Micro::UseSparcraftSimulation = true;
	} 

	// for each of our units
	for (const auto & kv : _unitData[_self].getUnits())
	{
		const UnitInfo & ui(kv.second);
		BWAPI::UnitType type = ui.type;

		// if the unit is a building
		if (type.isBuilding()) 
		{
			// update the enemy occupied regions
			updateOccupiedRegions(BWTA::getRegion(BWAPI::TilePosition(ui.lastPosition)), BWAPI::Broodwar->self());
		}
	}
}
Пример #23
0
// Get a sunken position depending on whether or not we have an expansion.
BWAPI::TilePosition BuildingManager::getSunkenPosition()
{

	BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony;
	// Always make sunkens at natural expansion if you can.
	if (createdHatcheriesSet.size() >= 1)
	{
		BWAPI::TilePosition hatchPosition = createdHatcheriesVector[0];
		BWAPI::Unit pExpansion = BWAPI::Broodwar->getClosestUnit(BWAPI::Position(hatchPosition), BWAPI::Filter::IsResourceDepot);
		BWAPI::Unitset myUnits = pExpansion->getUnitsInRadius(200);
		BWAPI::UnitType larva = BWAPI::UnitTypes::Zerg_Larva;
		BWAPI::UnitType egg = BWAPI::UnitTypes::Zerg_Egg;

		std::set<BWAPI::TilePosition> stuffBlocking;
		for (BWAPI::Unit p : myUnits)
		{
			if (p->getType() == larva || p->getType() == egg)
			{
				stuffBlocking.insert(p->getTilePosition());
			}
		}

		while (buildableSunkenTilePositions.size() >= 1)
		{
			std::set<BWAPI::TilePosition>::iterator it = buildableSunkenTilePositions.begin();


			BWAPI::TilePosition mySunkPosition = *it;
			Building z(sunk, mySunkPosition);

			if (!isCreepStarted())
			{
				if (BWAPI::Broodwar->hasCreep(mySunkPosition) && createdBuilding.find(mySunkPosition) == createdBuilding.end() && stuffBlocking.find(mySunkPosition) == stuffBlocking.end())
				{
					return *it;
				}
				else
				{
					buildableSunkenTilePositions.erase(*it);
				}
			}

			else
			{
				if (BWAPI::Broodwar->hasCreep(mySunkPosition) && BuildingPlacer::Instance().canBuildHere(mySunkPosition, z) && createdBuilding.find(mySunkPosition) == createdBuilding.end() && stuffBlocking.find(mySunkPosition) == stuffBlocking.end())
				{
					return *it;
				}
				else
				{
					buildableSunkenTilePositions.erase(*it);
				}

			}


		
		}


		//BWAPI::Position hatchPositionBWP = BWAPI::Position(hatchPosition);
		BWAPI::TilePosition sunkPosition;

		const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations();
		BWTA::BaseLocation *myLocation;

		for (BWTA::BaseLocation *p : locations) {
			BWAPI::TilePosition z = p->getTilePosition();
			if (z == hatchPosition){
				// This is the BWTA::Location of the first hatchery.
				myLocation = p;

			}
		}
		// Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set)
		const BWAPI::Unitset mineralSet = myLocation->getMinerals();
		//const std::set<BWAPI::Unit*> mineralSet = myLocation->getMinerals();

		int counter3 = 0;
		int theX = 0;
		int theY = 0;
		for (BWAPI::Unit p : mineralSet)
		{
			// Calculate the difference between LeftMostMineralPatch.x - ExpansionHatchery.x and store it in theX
			theX = p->getTilePosition().x - hatchPosition.x;
			// Calculate the difference between LeftMostMineralPatch.y - ExpansionHatchery.y and store it in theY
			theY = p->getTilePosition().y - hatchPosition.y;
			break;
		}

		int gasX = 0;
		int gasY = 0;
		int counter4 = 0;
		//Get all geysers near the expansion -- it should only return 1 for every map we play..
		const BWAPI::Unitset gasSet = myLocation->getGeysers();
		for (BWAPI::Unit p : gasSet)
		{
			// Calculate the difference between Geyser.x- ExpansionHatchery.x and store it in gasX
			gasX = p->getTilePosition().x - hatchPosition.x;
			// Calculate the difference between Geyser.y- ExpansionHatchery.y and store it in gasY
			gasY = p->getTilePosition().y - hatchPosition.y;
			break;
		}





		int newx, newy;

		int outercounter = 0;
		int counter = 0;
		newx = hatchPosition.x;
		newy = hatchPosition.y;

		int beginX = hatchPosition.x;
		int beginY = hatchPosition.y;

		
		//sunkPosition = BWAPI::TilePosition(newx, newy);

		//test4 = BuildingPlacer::Instance().canBuildHere(sunkPosition, b);

		// Form a new sunken position that starts at the hatchery positive.


		std::vector<bool> incrementDecrement(8);


		bool useGasX = false;
		bool useGasY = false;
		bool useMinX = false;
		bool useMinY = false;

		if (abs(gasX) > abs(gasY))
		{
			useGasX = true;
		}
		else
		{
			useGasY = true;
		}

		if (abs(theX) > abs(theY))
		{
			useMinX = true;
		}
		else
		{
			useMinY = true;
		}

		// Gas differences is probably more reliable than mineral differences.
		if (useGasX && useMinX)
		{
			useMinX = false;
			useMinY = true;
		}

		// Gas differences is probably more reliable than mineral differences.
		if (useGasY && useMinY)
		{
			useMinY = false;
			useMinX = true;
		}
		// This is where we decide which directions we can make sunkens in
		// It is based on X and Y differences in LeftMostMineral - Hatchery and Geyser - Hatchery
		// It is not very good right now because we only use two variables. We should use four variables for better dection : theX, theY, gasX, gasY

		// If the difference between LeftMostMineral.y - Hatchery.y is negative : It means the mierals are North of the hatchery
		// If the difference between Geyser.X - Hatchery.X is negative : It means that the geyser is Left of the Hatchery
		if (useMinY && useGasX)
		{
			if (theY < 0 && gasX < 0)
			{
				/* Allow the following directions for sunken to be built :
				Increase X & Keep Y the same (East)
				Increase X & Increase Y (Go South East)
				Decrease X & Increase Y  (Go South West)
				Keep X Same, Increase Y (Go South)

				Go NORTHEAST **Test**
				*/
				incrementDecrement = { true, false, true, true, false, false, true, false };

			}

			// If the difference between LeftMostMineral.y - Hatchery.y is positive : It means the mierals are South of the hatchery
			// If the difference between Geyser.X - Hatchery.X is negative : It means that the geyser is Left of the Hatchery
			else if (gasX < 0 && theY > 0)
			{
				/* Allow the following directions for sunken to be built :
				Increase X & Keep Y the same (East)
				Increase X & Decrease Y (Go North East)
				Decrease X & Decrease Y (Go North West)
				Keep X Same, Decrease Y (Go North)

				GO SOUTHEAST --> Test
				*/
				incrementDecrement = { false, true, true, false, true, false, false, true };
			}

			// If the difference between LeftMostMineral.y - Hatchery.y is negative : It means the mierals are North of the hatchery
			// If the difference between Geyser.X - Hatchery.X is positive : It means that the geyser is Right or East of the Hatchery
			else if (gasX > 0 && theY < 0)
			{
				/* Allow the following directions for sunken to be built :
				Decrease X & Keep Y the same (West)
				Decrease X & Increase Y (Go South West)
				Increase X & Increase Y  (Go South East)
				Keep X Same, Increase Y (Go South)

				Go Northwest
				*/
				incrementDecrement = { true, false, false, true, false, true, true, false };

			}

			// If the difference between LeftMostMineral.y - Hatchery.y is positive : It means the mierals are South of the hatchery
			// If the difference between Geyser.X - Hatchery.X is positive : It means that the geyser is Right or East of the Hatchery
			else if (theY > 0 && gasX > 0)
			{
				/* Decrease X & Keep Y the same (West)
				Decrease X & Decrease Y (Go North West)
				Increase X & Decrease Y (Go North East)
				Don't change X Decrease y (Go North)

				Go Southwest
				*/
				incrementDecrement = { false, true, false, false, true, true, false, true };

			}
		}


		else if (useMinX && useGasY)
		{
			// If the difference between LeftMostMineral.x - Hatchery.x is positive : It means the mierals are East of the hatchery
			// If the difference between Geyser.Y - Hatchery.Y is negative : It means that the geyser is North of the Hatchery
			if (gasY < 0 && theX > 0)
			{
				/* Decrease X(Go West)
				Increase Y(Go South)
				Decrease X, Increase Y(Go South West)
				Decrease X, Decrease Y(Go North West)
				I think can try SouthEast ? */
				incrementDecrement = { false, false, false, true, true, true, true, false };

			}

			// If the difference between LeftMostMineral.x - Hatchery.x is positive : It means the mierals are East of the hatchery
			// If the difference between Geyser.Y - Hatchery.Y is positive : It means that the geyser is South of the Hatchery
			else if (theX > 0 && gasY > 0)
			{
				/* Decrease X(Go West)
				Decrease Y(Go North)
				Decrease X, INcrease Y(Go SOuth West)
				Decrease X, Decrease Y(Go North West)
				I think can try NOrthEast?
				*/
				incrementDecrement = { false, false, false, true, true, true, false, true };

			}

			// If the difference between LeftMostMineral.x - Hatchery.x is negative : It means the minerals are West of the hatchery
			// If the difference between Geyser.Y - Hatchery.Y is negative : It means that the geyser is North of the Hatchery
			else if (gasY < 0 && theX < 0)
			{
				/* Increase X(Go East)
				Increase Y(Go South)
				Increase X, Increase Y(Go South East)
				Increase X, Decrease Y(Go North East)
				I think maybe Southwest is okay?.. Even NW might be okay */
				incrementDecrement = { true, true, true, false, false, false, true, false };
			}

			// If the difference between LeftMostMineral.x - Hatchery.x is negative : It means the minerals are West of the hatchery
			// If the difference between Geyser.Y - Hatchery.Y is positive : It means that the geyser is South of the Hatchery
			else if (gasY > 0 && theX < 0)
			{

				incrementDecrement = { true, true, true, false, false, false, false, true };
				/* Increase X(Go East)
				Decrease Y(Go North)
				Increase X, Increase Y(Go South East)
				Increase X, Decrease Y(Go North East)
				I think maybe Northwest is okay? */

			}
		}

		beginX = hatchPosition.x;
		beginY = hatchPosition.y;

		std::vector<std::pair<int, int> > myVec;
		std::pair<int, int> p1;

		for (int i = 0; i < 8; i++)
		{
			if (incrementDecrement[i])
			{
				if (i == 0)
				{
					p1.first = 1;
					p1.second = 1;
				}

				else if (i == 1)
				{
					p1.first = 1;
					p1.second = -1;
				}

				else if (i == 2)
				{
					p1.first = 1;
					p1.second = 0;
				}

				else if (i == 3)
				{
					p1.first = -1;
					p1.second = 1;
				}

				else if (i == 4)
				{
					p1.first = -1;
					p1.second = -1;
				}

				else if (i == 5)
				{
					p1.first = -1;
					p1.second = 0;
				}

				else if (i == 6)
				{
					p1.first = 0;
					p1.second = 1;
				}

				else if (i == 7)
				{
					p1.first = 0;
					p1.second = -1;
				}

				myVec.push_back(p1);
			}

		}


		for (int i = 0; i < 30; i++)
		for (int j = 0; j < 30; j++)
		for (int k = 0; k < 30; k++)
		for (int l = 0; l < 30; l++)
		{
			int xChange = beginX;
			int yChange = beginY;

			xChange += i * myVec[0].first;
			yChange += i * myVec[0].second;

			xChange += j * myVec[1].first;
			yChange += j * myVec[1].second;

			xChange += k * myVec[2].first;
			yChange += k * myVec[2].second;

			xChange += l * myVec[3].first;
			yChange += l * myVec[3].second;

			/*
			if (beginX + 1 == xChange) 
			{
				if (yChange == beginY)
				{
					BWAPI::Broodwar->printf("%d", xChange);
				}
				
			}
			*/
			sunkPosition = BWAPI::TilePosition(xChange, yChange);

			Building b(sunk, sunkPosition);

			if (!isCreepStarted())
			{
				if (BWAPI::Broodwar->hasCreep(sunkPosition) && stuffBlocking.find(sunkPosition) == stuffBlocking.end() && createdBuilding.find(sunkPosition) == createdBuilding.end())
				{
					buildableSunkenTilePositions.insert(sunkPosition);
				}
			}

			else
			{
				if (BWAPI::Broodwar->hasCreep(sunkPosition) && BuildingPlacer::Instance().canBuildHere(sunkPosition, b) && stuffBlocking.find(sunkPosition) == stuffBlocking.end() && createdBuilding.find(sunkPosition) == createdBuilding.end())
				{
					buildableSunkenTilePositions.insert(sunkPosition);
				}
			}

		}


		if (buildableSunkenTilePositions.size() != 0)
		{
			std::set<BWAPI::TilePosition>::iterator it = buildableSunkenTilePositions.begin();
			return *it;
		}
		else
		{
			return BWAPI::TilePositions::None;
		}
	}
}
Пример #24
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;
			}
		}
	}
}
Пример #26
0
BWAPI::TilePosition BuildingPlacer::getBuildLocationNear(const Building & b, int buildDist, bool horizontalOnly) const
{
    SparCraft::Timer t;
	t.start();

	BWTA::BaseLocation *home = findHome();
	BWAPI::TilePosition chokeTile = findChoke(home);

	int homex = home->getTilePosition().x;
	int homey = home->getTilePosition().y;
	int midx = (chokeTile.x + homex) / 2;
	int midy = (chokeTile.y + homey) / 2;
	static int px = midx;
	static int py = midy;

	// 1 if choke farther right, -1 if farther left
	int ix = chokeTile.x > midx ? 1 : -1;
	// 1 if choke farther south, -1 if farther north
	int iy = chokeTile.y < midy ? -1 : 1;

    // get the precomputed vector of tile positions which are sorted closes to this location
    const std::vector<BWAPI::TilePosition> & closestToBuilding = MapTools::Instance().getClosestTilesTo(BWAPI::Position(b.desiredPosition));

    double ms1 = t.getElapsedTimeInMilliSec();

    // special easy case of having no pylons
    int numPylons = BWAPI::Broodwar->self()->completedUnitCount(BWAPI::UnitTypes::Protoss_Pylon);
	int numGate = BWAPI::Broodwar->self()->completedUnitCount(BWAPI::UnitTypes::Protoss_Gateway);
	int numCan = BWAPI::Broodwar->self()->completedUnitCount(BWAPI::UnitTypes::Protoss_Photon_Cannon);

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

	if (BWAPI::Broodwar->mapName().compare(1,9,"Andromeda")) {
		if (b.type == BWAPI::UnitTypes::Protoss_Pylon && numPylons == 0) {
			BWAPI::TilePosition pos = drawPylon(midx, midy, ix, iy, b);
			if (pos != BWAPI::TilePositions::None) {
				px = pos.x;
				py = pos.y;
				return pos;
			}

		}

		else if (b.type == BWAPI::UnitTypes::Protoss_Forge) {
			BWAPI::TilePosition pos = drawForge(midx, midy, ix, iy, b);
			if (pos != BWAPI::TilePositions::None) {
				return pos;
			}
		}

		else if (b.type == BWAPI::UnitTypes::Protoss_Photon_Cannon) {
			BWAPI::TilePosition pos = drawProtonCannon(homex, homey, ix, iy, b);
			if (pos != BWAPI::TilePositions::None) {
				return pos;
			}
		}

		//else if (b.type == BWAPI::UnitTypes::Protoss_Gateway && numGate == 0) {
		//	return drawGateway(homex, homey, ix, iy, b);
		//}

	}

	// iterate through the list until we've found a suitable location
	for (size_t i(0); i < closestToBuilding.size(); ++i)
	{
		if (b.type == BWAPI::UnitTypes::Protoss_Gateway && numGate == 0) {
			buildDist = 0;
		}
		if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly))
		{
			double ms = t.getElapsedTimeInMilliSec();
			//BWAPI::Broodwar->printf("Building Placer Took %d iterations, lasting %lf ms @ %lf iterations/ms, %lf setup ms", i, ms, (i / ms), ms1);

			return closestToBuilding[i];
		}
	}

	double ms = t.getElapsedTimeInMilliSec();
	//BWAPI::Broodwar->printf("Building Placer Took %lf ms", ms);
	

	return  BWAPI::TilePositions::None;
}
Пример #27
0
// STEP 6: CHECK FOR COMPLETED BUILDINGS
void BuildingManager::checkForCompletedBuildings()
{
	std::vector<Building> toRemove;

	// for each of our buildings under construction
	for (auto & b : _buildings)
	{
		if (b.status != BuildingStatus::UnderConstruction)
		{
			continue;
		}

		// if the unit has completed
		if (b.buildingUnit->isCompleted())
		{
			if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Zerg)
			{
				if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Creep_Colony)
				{
					//b.buildingUnit->upgrade(b.buildingUnit->getUpgrade());
					//b.buildingUnit->buildAddon(BWAPI::UnitTypes::Zerg_Sunken_Colony);
					
					// MAKE SUNKEN
					//b.buildingUnit->morph(BWAPI::UnitTypes::Zerg_Sunken_Colony);
					//MetaType type(BWAPI::UnitTypes::Zerg_Sunken_Colony);
					//ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);

				}
				
				if (b.buildingUnit->getType() == BWAPI::UnitTypes::Zerg_Hatchery)
				{
					MetaType type(BWAPI::UnitTypes::Zerg_Creep_Colony);
					ProductionManager::Instance()._queue.queueAsHighestPriority(type, true);
					createdHatchery = true;
				}
				/*
					for (BWAPI::Unit p : BWAPI::Broodwar->self()->getUnits())
					{
						if (!madeFirstSunken && p->getType().isWorker() && p->getPosition() == firstHatcheryPosition)
						{
							//BWAPI::Position tempPosition;
							//tempPosition.x = b.finalPosition.x + 3;
							//tempPosition.y = b.finalPosition.y + 3;
					
							/*
							BWAPI::TilePosition sunkPos = getSunkenPosition();


							createdSunkenSet.insert(sunkPos);
							createdSunkenVector.push_back(sunkPos);
							createdBuilding.insert(sunkPos);
							p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos);

							madeFirstSunken = true;


							BWAPI::TilePosition sunkPos2 = getSunkenPosition();


							createdSunkenSet.insert(sunkPos2);
							createdSunkenVector.push_back(sunkPos2);
							createdBuilding.insert(sunkPos2);
							p->build(BWAPI::UnitTypes::Zerg_Hatchery, sunkPos2);
							//b.builderUnit->build(b.type, b.finalPosition);
							
							break;
							
							//candidateProducers.insert(p);
						}
					}
				}
			*/

			}
			// if we are terran, give the worker back to worker manager
			if (BWAPI::Broodwar->self()->getRace() == BWAPI::Races::Terran)
			{
				if (b.isGasSteal)
				{
					ScoutManager::Instance().setWorkerScout(b.builderUnit);
				}
				// otherwise tell the worker manager we're finished with this unit
				else
				{
					WorkerManager::Instance().finishedWithWorker(b.builderUnit);
				}
			}



			// remove this unit from the under construction vector
			toRemove.push_back(b);
		}
		else
		{
			
			if (b.type == 131 && b.buildingUnit->getHitPoints() >= 1050 && !sentFirstDroneForSunken)
			{

				BWAPI::UnitType sunk = BWAPI::UnitTypes::Zerg_Creep_Colony;
				Building z(sunk, createdHatcheriesVector[0]);
				BWAPI::Unit workerToAssign = WorkerManager::Instance().getBuilder(z);
				BWAPI::Unit workerToAssign2 = WorkerManager::Instance().getBuilder(z);

				const std::set<BWTA::BaseLocation*, std::less<BWTA::BaseLocation*>> locations = BWTA::getBaseLocations();
				BWTA::BaseLocation *myLocation;

				for (BWTA::BaseLocation *p : locations) {
					BWAPI::TilePosition z = p->getTilePosition();
					if (z == createdHatcheriesVector[0]){
						// This is the BWTA::Location of the first hatchery.
						myLocation = p;
					}
				}
				// Get the set of mineral patches closest to BWTA::Location of the hatchery(it will return like 8 mineral patches usually in the set)
				const BWAPI::Unitset mineralSet = myLocation->getMinerals();

				BWAPI::Unit myMineral;
				for (BWAPI::Unit p : mineralSet)
				{
					myMineral = p;
					break;
				}



				workerToAssign->gather(myMineral);
				workerToAssign2->gather(myMineral);
				sunkenUnit = workerToAssign;
				sunkenUnit2 = workerToAssign2;

				sentFirstDroneForSunken = true;
				
			}
			int x = 0;
			
		}
	}

	removeBuildings(toRemove);
}