예제 #1
0
TilePosition StructureAgent::getNextScanLocation()
{
	TilePosition ePos = ExplorationManager::getInstance()->getClosestSpottedBuilding(Broodwar->self()->getStartLocation());
	if (ePos.x() > -1)
	{
		//Already found enemy base
		return TilePosition(-1, -1);
	}

	for(set<BaseLocation*>::const_iterator i=getStartLocations().begin();i!=getStartLocations().end();i++)
	{
		TilePosition basePos = (*i)->getTilePosition();

		bool needScan = true;

		//1. Check previous scans
		for (int i = 0; i < (int)hasScanned.size(); i++)
		{
			if (hasScanned.at(i).x() == basePos.x() && hasScanned.at(i).y() == basePos.y())
			{
				needScan = false;
			}
		}

		//2. Check if we have this base
		vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents();
		for (int i = 0; i < (int)agents.size(); i++)
		{
			if (agents.at(i)->isAlive())
			{
				double dist = basePos.getDistance(agents.at(i)->getUnit()->getTilePosition());
				if (dist <= 10)
				{
					needScan = false;
					break;
				}
			}
		}

		//3. Check if enemy units are near
		for(set<Unit*>::const_iterator j=Broodwar->enemy()->getUnits().begin();j!=Broodwar->enemy()->getUnits().end();j++)
		{
			if ((*j)->exists())
			{
				double dist = basePos.getDistance((*j)->getTilePosition());
				if (dist <= 10)
				{
					needScan = false;
					break;
				}
			}
		}

		if (needScan)
		{
			return basePos;
		}
	}
	return TilePosition(-1, -1);
}
예제 #2
0
void ExplorationManager::unitDestroyed(Unit* unit)
{
	TilePosition uPos = unit->getTilePosition();
	if (unit->getType().isBuilding())
	{
		bool removed = false;
		for (int i = 0; i < (int)spottedBuildings.size(); i++)
		{
			TilePosition sPos = spottedBuildings.at(i)->getTilePosition();
			if (uPos.x() == sPos.x() && uPos.y() == sPos.y())
			{
				spottedBuildings.at(i)->setInactive();
				removed = true;
			}
		}

		if (!removed)
		{
			//Broodwar->printf("[EM]: Building %s at (%d,%d) was not removed from EM!!!", unit->getType().getName().c_str(), uPos.x(), uPos.y());
		}
	}
	else
	{
		for (int i = 0; i < (int)spottedUnits.size(); i++)
		{
			if (spottedUnits.at(i)->getUnitID() == unit->getID())
			{
				spottedUnits.at(i)->setInactive();
				//Broodwar->printf("[EM]: Remove %s at (%d,%d)", unit->getType().getName().c_str(), uPos.x(), uPos.y());
			}
		}
	}
}
예제 #3
0
bool PFManager::moveToGoal(BaseAgent* agent,  TilePosition checkpoint, TilePosition goal)
{
	if (checkpoint.x() == -1 || goal.x() == -1) return false;
	Unit* unit = agent->getUnit();

	if (unit->isStartingAttack() || unit->isAttacking())
	{
		return false;
	}

	Position toReach = Position(checkpoint);
	double distToReach = toReach.getDistance(unit->getPosition());

	int engageDist = unit->getType().groundWeapon().maxRange();
	if (agent->isOfType(UnitTypes::Terran_Medic))
	{
		engageDist = 6 * 32;
	}
	if (engageDist <= 64)
	{
		engageDist = 64;
	}
	
	if (distToReach <= engageDist)
	{
		if (unit->isMoving()) unit->stop();
		return true;
	}
	
	//Move
	if (!unit->isMoving()) return unit->attack(toReach);
	else return true;
}
예제 #4
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
bool Squad::isVisible(TilePosition pos)
{
	if (!ExplorationManager::canReach(Broodwar->self()->getStartLocation(), pos))
	{
		return true;
	}

	if (Broodwar->isVisible(pos))
	{
		return true;
	}

	if (getCenter().getDistance(pos) <= 3)
	{
		return true;
	}

	for (int i = 0; i < (int)hasVisited.size(); i++)
	{
		TilePosition vPos = hasVisited.at(i);
		if (vPos.x() == pos.x() && vPos.y() == pos.y())
		{
			return true;
		}
	}

	return false;
}
예제 #5
0
void UnitClass::drawUnitTilePosition()
{
	TilePosition tile = getTilePosition();
	BWAPI::UnitType type = getType();
	Player player = getPlayer();

	BWAPI::Broodwar->drawBox(BWAPI::CoordinateType::Map, tile.x()*32, tile.y()*32, (tile.x()+type.tileWidth())*32, (tile.y()+type.tileHeight())*32, player->getColor());
}
예제 #6
0
void CoverMap::blockPosition(TilePosition buildSpot)
{
	if (buildSpot.x() == -1)
	{
		//Error check
		return;
	}
	cover_map[buildSpot.x()][buildSpot.y()] = BLOCKED;
}
예제 #7
0
bool CoverMap::canBuildAt(UnitType toBuild, TilePosition pos)
{
	int maxW = w - toBuild.tileWidth() - 1;
	int maxH = h - toBuild.tileHeight() - 1;

	//Out of bounds check
	if (pos.x() >= 0 && pos.x() < maxW && pos.y() >= 0 && pos.y() < maxH)
	{
		if (canBuild(toBuild, pos))
		{
			return true;
		}
	}
	return false;
}
예제 #8
0
bool Commander::isOccupied(BWTA::Region* region)
{
	BWTA::Polygon p = region->getPolygon();
	vector<BaseAgent*> agents = AgentManager::getInstance()->getAgents();
	for (int i = 0; i < (int)agents.size(); i++)
	{
		BaseAgent* agent = agents.at(i);
		if (agent->isAlive() && agent->getUnitType().isResourceDepot())
		{
			BWTA::Region* aRegion = getRegion(agents.at(i)->getUnit()->getTilePosition());
			Position c1 = region->getCenter();
			Position c2 = aRegion->getCenter();
			if (c2.x() == c1.x() && c2.y() == c1.y())
			{
				return true;
			}
		}
	}
	
	//Check expansion site
	TilePosition expansionSite = ExplorationManager::getInstance()->getExpansionSite();
	TilePosition center = TilePosition(region->getCenter());
	if (expansionSite.x() >= 0)
	{
		double dist = expansionSite.getDistance(center);
		if (dist <= 15)
		{
			return true;
		}
	}

	return false;
}
예제 #9
0
void UnitClass::build(TilePosition target, BWAPI::UnitType type)
{
	if(exists())
	{
		const Position targetPosition(target.x()*32+type.tileWidth()*16, target.y()*32+type.tileHeight()*16);
		if(getDistance(type, targetPosition) > 48 || !MapHelper::isAllVisible(target, type))
		{
			move(targetPosition, 0);
			return;
		}

		if(mUnit->getOrder() == BWAPI::Orders::PlaceBuilding)
		{
			if(mUnit->getBuildType() == type && mUnit->getOrderTargetPosition() == targetPosition)
				return;
		}

		if(mUnit->getLastCommand().getType() == BWAPI::UnitCommandTypes::Build && mUnit->getLastCommand().getUnitType() == type && mUnit->getLastCommand().getTargetTilePosition() == target)
		{
			if(mLastOrderExecuteTime >= BWAPI::Broodwar->getFrameCount())
				return;
		}

		if(mUnit->build(target, type))
			mLastOrderExecuteTime = BWAPI::Broodwar->getFrameCount() + BWAPI::Broodwar->getRemainingLatencyFrames();
		else
			move(targetPosition, 0);
	}
}
예제 #10
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
void Squad::removeMember(BaseAgent* agent)
{
	//Step 1. Remove the agent instance
	for (int i = 0; i < (int)agents.size(); i++)
	{
		if (agents.at(i)->getUnitID() == agent->getUnitID())
		{
			agents.at(i)->setSquadID(-1);
			agents.at(i)->assignToDefend();
			agents.erase(agents.begin() + i);
			break;
		}
	}

	//Step 2. Update the setup list
	for (int i = 0; i < (int)setup.size(); i++)
	{
		if (setup.at(i).equals(agent->getUnitType()))
		{
			setup.at(i).current--;
		}
	}

	//Step 3. If Explorer, set destination as explored (to avoid being killed at the same
	//place over and over again).
	if (isExplorer())
	{
		TilePosition goal = agent->getGoal();
		if (goal.x() >= 0)
		{
			ExplorationManager::Instance().setExplored(goal);
		}
	}
}
예제 #11
0
TilePosition ExplorationManager::scanForVulnerableBase()
{
	TilePosition spot = TilePosition(-1, -1);
	for (int i = 0; i < (int)spottedBuildings.size(); i++)
	{
		if (spottedBuildings.at(i)->isActive())
		{
			SpottedObject* obj = spottedBuildings.at(i);
			if (obj->getType().isResourceDepot())
			{
				if (!isDetectorCovering(obj->getTilePosition()))
				{
					//Broodwar->printf("Found probable vulnerable base at (%d,%d)", obj->getTilePosition().x(), obj->getTilePosition().y());
					spot = obj->getTilePosition();
				}
			}
		}
	}

	if (spot.x() < 0)
	{
		//Broodwar->printf("Scan: No vulnerable base found");
	}

	return spot;
}
예제 #12
0
TilePosition CoverMap::findBuildSpot(UnitType toBuild, TilePosition start)
{
	//Check start pos
	if (canBuildAt(toBuild, start)) return start;

	//Search outwards
	bool found = false;
	int cDiff = 1;
	TilePosition spot = TilePosition(-1, -1);
	while (!found) 
	{
		//Top
		TilePosition s = TilePosition(start.x() - cDiff, start.y() - cDiff);
		TilePosition e = TilePosition(start.x() + cDiff, start.y() - cDiff);
		spot = findSpotAtSide(toBuild, s, e);
		if (spot.x() != -1 && spot.y() != -1)
		{
			found = true;
			break;
		}

		//Bottom
		s = TilePosition(start.x() - cDiff, start.y() + cDiff);
		e = TilePosition(start.x() + cDiff, start.y() + cDiff);
		spot = findSpotAtSide(toBuild, s, e);
		if (spot.x() != -1 && spot.y() != -1)
		{
			found = true;
			break;
		}

		//Left
		s = TilePosition(start.x() - cDiff, start.y() - cDiff);
		e = TilePosition(start.x() - cDiff, start.y() + cDiff);
		spot = findSpotAtSide(toBuild, s, e);
		if (spot.x() != -1 && spot.y() != -1)
		{
			found = true;
			break;
		}

		//Right
		s = TilePosition(start.x() + cDiff, start.y() - cDiff);
		e = TilePosition(start.x() + cDiff, start.y() + cDiff);
		spot = findSpotAtSide(toBuild, s, e);
		if (spot.x() != -1 && spot.y() != -1)
		{
			found = true;
			break;
		}

		cDiff++;
		if (cDiff > range) found = true;
	}
	
	return spot;
}
예제 #13
0
TilePosition Commander::findChokePoint()
{
	//First, check the DefenseLocator
	//for a stored defense position.
	DefenseLocator* df = DefenseLocator::getInstance();
	TilePosition storedPos = df->getBaseDefensePos(Broodwar->mapHash());
	if (storedPos.x() != -1) return storedPos;

	double bestPrio = -1;
	Chokepoint* bestChoke = NULL;
	
	for(set<BWTA::Region*>::const_iterator i=getRegions().begin();i!=getRegions().end();i++)
	{
		if (isOccupied((*i)))
		{
			for(set<Chokepoint*>::const_iterator c=(*i)->getChokepoints().begin();c!=(*i)->getChokepoints().end();c++)
			{
				if (isEdgeChokepoint((*c)))
				{
					double cPrio = getChokepointPrio(TilePosition((*c)->getCenter()));
					if (cPrio > bestPrio)
					{
						bestPrio = cPrio;
						bestChoke = (*c);
					}
				}
			}
		}
	}

	TilePosition guardPos = Broodwar->self()->getStartLocation();
	if (bestChoke != NULL)
	{
		guardPos = findDefensePos(bestChoke);
		//guardPos = TilePosition(bestChoke->getCenter());

		//Pre-calculate path
		TilePosition b = ExplorationManager::getInstance()->getClosestSpottedBuilding(guardPos);
		if (b.x() >= 0)
		{
			Pathfinder::getInstance()->requestPath(guardPos, b);
		}
	}

	return guardPos;
}
예제 #14
0
void ExplorationManager::setExpansionSite(TilePosition pos)
{
	if (pos.x() >= 0)
	{
		siteSetFrame = Broodwar->getFrameCount();
		expansionSite = pos;
	}
}
예제 #15
0
bool CoverMap::positionFree(TilePosition pos)
{
	if (cover_map[pos.x()][pos.y()] == BUILDABLE)
	{
		return true;
	}
	return false;
}
예제 #16
0
bool AgentManager::unitsInArea(TilePosition pos, int tileWidth, int tileHeight, int unitID)
{
	for (int i = 0; i < (int)agents.size(); i++)
	{
		if (agents.at(i)->isAlive())
		{
			if (agents.at(i)->getUnit()->getID() != unitID)
			{
				TilePosition aPos = agents.at(i)->getUnit()->getTilePosition();
				if (aPos.x() >= pos.x() && aPos.x() <= pos.x() + tileWidth && aPos.y() >= pos.y() && aPos.y() <= pos.y() + tileWidth)
				{
					return true;
				}
			}
		}
	}
	return false;
}
예제 #17
0
bool ExplorationManager::canReach(TilePosition a, TilePosition b)
{
	int w = Broodwar->mapWidth();
	int h = Broodwar->mapHeight();
	if (a.x() < 0 || a.x() >= w || a.y() < 0 || a.y() >= h)
	{
		return false;
	}
	if (b.x() < 0 || b.x() >= w || b.y() < 0 || b.y() >= h)
	{
		return false;
	}
	bool ok = true;

	ok = a.hasPath(b);
	
	return ok;
}
예제 #18
0
TilePosition CoverMap::findSpotAtSide(UnitType toBuild, TilePosition start, TilePosition end)
{
	int dX = end.x() - start.x();
	if (dX != 0) dX = 1;
	int dY = end.y() - start.y();
	if (dY != 0) dY = 1;

	TilePosition cPos = start;
	bool done = false;
	while (!done) 
	{
		if (canBuildAt(toBuild, cPos)) return cPos;
		int cX = cPos.x() + dX;
		int cY = cPos.y() + dY;
		cPos = TilePosition(cX, cY);
		if (cPos.x() == end.x() && cPos.y() == end.y()) done = true;
	}

	return TilePosition(-1, -1);
}
예제 #19
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
void Squad::defend(TilePosition mGoal)
{
	if (mGoal.x() == -1 || mGoal.y() == -1) return;

	if (currentState != STATE_DEFEND)
	{
		if (currentState == STATE_ASSIST && !isUnderAttack())
		{
			currentState = STATE_DEFEND;
		}
	}
	setGoal(mGoal);
}
예제 #20
0
void Commander::updateGoals()
{
	TilePosition defSpot = findChokePoint();
	
	if (defSpot.x() != -1)
	{
		for (int i = 0; i < (int)squads.size(); i++)
		{
			Squad* sq = squads.at(i);
			squads.at(i)->defend(defSpot);
		}
	}
}
예제 #21
0
void Commander::forceAttack()
{
	TilePosition cGoal = getClosestEnemyBuilding(Broodwar->self()->getStartLocation());
	Broodwar->printf("[%d] Launch attack (%d,%d)", Broodwar->getFrameCount(), cGoal.x(), cGoal.y());
	if (cGoal.x() == -1)
	{
		return;
	}

	for (int i = 0; i < (int)squads.size(); i++)
	{
		if (squads.at(i)->isOffensive() || squads.at(i)->isSupport())
		{
			if (cGoal.x() >= 0)
			{
				squads.at(i)->forceActive();
				squads.at(i)->attack(cGoal);
			}
		}
	}

	currentState = ATTACK;
}
예제 #22
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
bool Squad::isThisGoal(TilePosition mGoal)
{
	int xDiff = goal.x() - mGoal.x();
	if (xDiff < 0) xDiff *= -1;
	int yDiff = goal.y() - mGoal.y();
	if (yDiff < 0) yDiff *= -1;

	//Broodwar->printf("SQ %d: (%d,%d) = (%d,%d)", id, goal.x(), goal.y(), mGoal.x(), mGoal.y());
	if (xDiff <= 2 && yDiff <= 2)
	{
		return true;
	}
	return false;
}
예제 #23
0
double Commander::getChokepointPrio(TilePosition center)
{
	TilePosition ePos = ExplorationManager::getInstance()->getClosestSpottedBuilding(center);

	if (ePos.x() >= 0)
	{
		double dist = ePos.getDistance(center);
		return 1000 - dist;
	}
	else
	{
		double dist = Broodwar->self()->getStartLocation().getDistance(center);
		return dist;
	}
}
예제 #24
0
void BTHAIModule::onNukeDetect(BWAPI::Position target) 
{
	// TODO: React on this! Make all units move outside of the blast radius?
	//		 Notify the commander and let it make a decision?
	if (target != Positions::Unknown) 
	{
		TilePosition t = TilePosition(target);
		Broodwar->printf("Nuclear Launch Detected at (%d,%d)",t.x(),t.y());

		Commander::Instance().onNukeDetect(target);
	}
	else
	{
		Broodwar->printf("Nuclear Launch Detected");
	}
}
예제 #25
0
void BuildPlanner::expand(UnitType commandCenterUnit)
{
	if (containsType(commandCenterUnit))
	{
		return;
	}

	TilePosition pos = CoverMap::getInstance()->findExpansionSite();
	if (pos.x() == -1)
	{
		//No expansion site found.
		return;
	}

	addBuildingFirst(commandCenterUnit);
}
예제 #26
0
bool Commander::shallEngage()
{
	TilePosition closeEnemy = getClosestEnemyBuilding(Broodwar->self()->getStartLocation());
	if (closeEnemy.x() == -1)
	{
		//No enemy sighted. Dont launch attack.
		return false;
	}

	for (int i = 0; i < (int)squads.size(); i++)
	{
		if (squads.at(i)->isRequired() && !squads.at(i)->isActive())
		{
			return false;
		}
	}
	return true;
}
예제 #27
0
void ExplorationSquad::computeActions()
{
	if (!active)
	{
		if (isFull())
		{
			active = true;
		}
		return;
	}

	//First, remove dead agents
	for(int i = 0; i < (int)agents.size(); i++)
	{
		if(!agents.at(i)->isAlive())
		{
			agents.erase(agents.begin() + i);
			i--;
		}
	}

	//All units dead, go back to inactive
	if ((int)agents.size() == 0)
	{
		active = false;
		return;
	}

	if (active)
	{
		if (activePriority != priority)
		{
			priority = activePriority;
		}

		TilePosition nGoal = ExplorationManager::Instance().getNextToExplore(this);
		if (nGoal.x() >= 0)
		{
			this->goal = nGoal;
			setMemberGoals(goal);
		}
	}
}
예제 #28
0
Corners CoverMap::getCorners(UnitType type, TilePosition center)
{
	int x1 = center.x();
	int y1 = center.y();
	int x2 = x1 + type.tileWidth() - 1;
	int y2 = y1 + type.tileHeight() - 1;

	int margin = 1;
	if (type.canProduce())
	{
		margin = 1;
	}

	if (BaseAgent::isOfType(type, UnitTypes::Terran_Supply_Depot))
	{
		margin = 0;
	}
	if (BaseAgent::isOfType(type, UnitTypes::Protoss_Pylon))
	{
		margin = 0;
	}

	x1 -= margin;
	x2 += margin;
	y1 -= margin;
	y2 += margin;

	//Special case: Terran Addon buildings
	//Add 2 extra spaces to the right to make space for the addons.
	if (BaseAgent::isOfType(type, UnitTypes::Terran_Factory) || BaseAgent::isOfType(type, UnitTypes::Terran_Starport) || BaseAgent::isOfType(type, UnitTypes::Terran_Command_Center) || BaseAgent::isOfType(type, UnitTypes::Terran_Science_Facility))
	{
		x2 += 2;
	}

	Corners c;
	c.x1 = x1;
	c.y1 = y1;
	c.x2 = x2;
	c.y2 = y2;

	return c;
}
예제 #29
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
void Squad::attack(TilePosition mGoal)
{
	if (mGoal.x() == -1 || mGoal.y() == -1) return;
	
	if (currentState != STATE_ATTACK)
	{
		if (!isUnderAttack())
		{
			if (isActive())
			{
				currentState = STATE_ATTACK;
			}
		}
	}

	if (isActive())
	{
		setGoal(mGoal);
	}
}
예제 #30
0
파일: Squad.cpp 프로젝트: rarosu/FnulAI
void Squad::assist(TilePosition mGoal)
{
	if (mGoal.x() == -1 || mGoal.y() == -1) return;

	if (currentState != STATE_ASSIST)
	{
		if (!isUnderAttack() && currentState == STATE_DEFEND)
		{
			currentState = STATE_ASSIST;
			setGoal(mGoal);
		}
	}
	else
	{
		if (goal.x() == -1)
		{
			setGoal(mGoal);
		}
	}
}