示例#1
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);
}
//ctx add
BWAPI::TilePosition BuildingPlacer::getBuildLocationFarFromChokePoint(const Building & b, int buildDist, bool horizontalOnly, bool flag) const
{
	SparCraft::Timer t;
	t.start();

	BWAPI::TilePosition startTitlePos = BWAPI::Broodwar->self()->getStartLocation();
	BWTA::Chokepoint *chokePoint = BWTA::getNearestChokepoint(startTitlePos);
	BWAPI::Position chokeCenterPosition = chokePoint->getCenter();
	BWTA::Region *baseRegion = BWTA::getRegion(BWAPI::Broodwar->self()->getStartLocation());
	BWTA::Polygon basePolygon = baseRegion->getPolygon();
	BWAPI::Position farPosition =  BWAPI::Position(0, 0);
	BWAPI::TilePosition resultPosition = BWAPI::TilePosition(0, 0);
	double dis = 0.0;

	

	for (int i = 0; i < (int)basePolygon.size(); i++) {
		BWAPI::Position point = basePolygon[i];
		double ms1 = t.getElapsedTimeInMilliSec();
		if (point.getDistance(chokeCenterPosition) > dis) {
			dis = point.getDistance(chokeCenterPosition);
			farPosition = point;
		}
	}

	const std::vector<BWAPI::TilePosition> & closestToBuilding = MapTools::Instance().getClosestTilesTo(BWAPI::Position(b.desiredPosition));

	//get best solution
	dis = farPosition.getDistance(BWAPI::Position(startTitlePos));
	
	if (flag == true) {
		for (size_t i = 0; i < closestToBuilding.size(); ++i)
		{
			double ms1 = t.getElapsedTimeInMilliSec();
			if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis > farPosition.getDistance(BWAPI::Position(closestToBuilding[i])))
			{
				resultPosition = closestToBuilding[i];
				break;
				//return closestToBuilding[i];
			}
		}
	}
	else {
		for (size_t i = 0; i < closestToBuilding.size(); ++i)
		{
			double ms1 = t.getElapsedTimeInMilliSec();
			if (canBuildHereWithSpace(closestToBuilding[i], b, buildDist, horizontalOnly) && dis < farPosition.getDistance(BWAPI::Position(closestToBuilding[i])))
			{
				resultPosition = closestToBuilding[i];
				break;
				//return closestToBuilding[i];
			}
		}
	}
	
	if (!basePolygon.isInside(BWAPI::Position(resultPosition))) {
		resultPosition = getBuildLocationNear(b, buildDist, horizontalOnly);
	}

	return resultPosition;
}
示例#3
0
void ProductionManager::buildBunker() {
	BWAPI::Position base = BWAPI::Position(BWAPI::Broodwar->self()->getStartLocation());
	BWTA::Chokepoint *entrance = BWTA::getNearestChokepoint(base); 
	MetaType bunker = MetaType(BWAPI::UnitTypes::Terran_Bunker);
	BWAPI::Unit producer = ProductionManager::Instance().getProducer(bunker, entrance->getCenter());

	int numBarracks = BWAPI::Broodwar->self()->allUnitCount(BWAPI::UnitTypes::Terran_Barracks);
	bool canMake = canMakeNow(producer, bunker);

	Building b(bunker.getUnitType(), BWAPI::TilePosition(entrance->getCenter()));
	b.isGasSteal = false;

	// set the producer as the closest worker, but do not set its job yet
	producer = WorkerManager::Instance().getBuilder(b, false);
	// get a possible building location for the building
	
	if (!_haveLocationForThisBuilding)
	{
		_predictedTilePosition = BuildingManager::Instance().getBuildingLocation(b);
	}

	if (_predictedTilePosition != BWAPI::TilePositions::None)
	{
		_haveLocationForThisBuilding = true;
	}

	if (producer && canMake && (numBarracks > 0))
	{
		// create it
		create(producer, BuildOrderItem(bunker, 1, true));
		_assignedWorkerForThisBuilding = false;
		_haveLocationForThisBuilding = false;

		// draw a box where the building will be placed
		int x1 = _predictedTilePosition.x * 32;
		int x2 = x1 + (b.type.tileWidth()) * 32;
		int y1 = _predictedTilePosition.y * 32;
		int y2 = y1 + (b.type.tileHeight()) * 32;
		if (Config::Debug::DrawWorkerInfo)
		{
			BWAPI::Broodwar->drawBoxMap(x1, y1, x2, y2, BWAPI::Colors::Blue, false);
		}

		// where we want the worker to walk to
		BWAPI::Position walkToPosition = BWAPI::Position(x1 + (b.type.tileWidth() / 2) * 32, y1 + (b.type.tileHeight() / 2) * 32);

		// compute how many resources we need to construct this building
		int mineralsRequired = std::max(0, b.type.mineralPrice() - getFreeMinerals());
		int gasRequired = std::max(0, b.type.gasPrice() - getFreeGas());

		// get a candidate worker to move to this location
		BWAPI::Unit moveWorker = WorkerManager::Instance().getMoveWorker(walkToPosition);

		// Conditions under which to move the worker: 
		//		- there's a valid worker to move
		//		- we haven't yet assigned a worker to move to this location
		//		- the build position is valid
		//		- we will have the required resources by the time the worker gets there
		if (moveWorker && _haveLocationForThisBuilding && !_assignedWorkerForThisBuilding && (_predictedTilePosition != BWAPI::TilePositions::None) &&
			WorkerManager::Instance().willHaveResources(mineralsRequired, gasRequired, moveWorker->getDistance(walkToPosition)))
		{
			// we have assigned a worker
			_assignedWorkerForThisBuilding = true;

			// tell the worker manager to move this worker
			WorkerManager::Instance().setMoveWorker(mineralsRequired, gasRequired, walkToPosition);
		}
	}
}