void checkSupportedUnitType(const BWAPI::UnitType & type) { if (type == BWAPI::UnitTypes::None || type == BWAPI::UnitTypes::Unknown) { System::FatalError("Unknown unit type in experiment file"); } if (type == BWAPI::UnitTypes::Protoss_Corsair || type == BWAPI::UnitTypes::Zerg_Devourer || type == BWAPI::UnitTypes::Zerg_Scourge || type == BWAPI::UnitTypes::Terran_Valkyrie) { System::FatalError("Units with just air weapons currently not supported correctly: " + type.getName()); } if (type.isBuilding() && (type != BWAPI::UnitTypes::Protoss_Photon_Cannon || type != BWAPI::UnitTypes::Zerg_Sunken_Colony || type != BWAPI::UnitTypes::Terran_Missile_Turret)) { System::FatalError("Non-attacking buildings not currently supported: " + type.getName()); } if (type.isSpellcaster()) { System::FatalError("Spell casting units not currently supported: " + type.getName()); } }
// selects a unit of a given type BWAPI::Unit ProductionManager::selectUnitOfType(BWAPI::UnitType type, BWAPI::Position closestTo) { // if we have none of the unit type, return nullptr right away if (BWAPI::Broodwar->self()->completedUnitCount(type) == 0) { return nullptr; } BWAPI::Unit unit = nullptr; // if we are concerned about the position of the unit, that takes priority if (closestTo != BWAPI::Positions::None) { double minDist(1000000); for (auto & u : BWAPI::Broodwar->self()->getUnits()) { if (u->getType() == type) { double distance = u->getDistance(closestTo); if (!unit || distance < minDist) { unit = u; minDist = distance; } } } // if it is a building and we are worried about selecting the unit with the least // amount of training time remaining } else if (type.isBuilding()) { for (auto & u : BWAPI::Broodwar->self()->getUnits()) { UAB_ASSERT(u != nullptr, "Unit was null"); if (u->getType() == type && u->isCompleted() && !u->isTraining() && !u->isLifted() &&u->isPowered()) { return u; } } // otherwise just return the first unit we come across } else { for (auto & u : BWAPI::Broodwar->self()->getUnits()) { UAB_ASSERT(u != nullptr, "Unit was null"); if (u->getType() == type && u->isCompleted() && u->getHitPoints() > 0 && !u->isLifted() &&u->isPowered()) { return u; } } } // return what we've found so far return nullptr; }
// UnitType constructor ActionTypeData::ActionTypeData(BWAPI::UnitType t, const ActionID id) : type (UnitType) , unit (t) , raceID (GetRaceID(t.getRace())) , actionID (id) , mineralPriceVal (t.mineralPrice() * Constants::RESOURCE_SCALE) , gasPriceVal (t.gasPrice() * Constants::RESOURCE_SCALE) , supplyRequiredVal (t.supplyRequired()) , supplyProvidedVal (t.supplyProvided()) , buildTimeVal (t.buildTime()) , numberProduced (1) , name (t.getName()) , metaName (t.getName()) , building (t.isBuilding()) , worker (t.isWorker()) , refinery (t.isRefinery()) , resourceDepot (t.isResourceDepot()) , supplyProvider (t.supplyProvided() > 0 && !t.isResourceDepot()) , canProduceBool (t.isBuilding() && t.canProduce()) , canAttackBool (t.canAttack()) , whatBuildsUnitType (t.whatBuilds().first) , addon (t.isAddon()) , morphed (false) , reqAddon (false) , reqAddonID (0) { if (t == BWAPI::UnitTypes::Zerg_Zergling || t == BWAPI::UnitTypes::Zerg_Scourge) { numberProduced = 2; } if (t == BWAPI::UnitTypes::Zerg_Lair || t == BWAPI::UnitTypes::Zerg_Hive || t == BWAPI::UnitTypes::Zerg_Greater_Spire || t == BWAPI::UnitTypes::Zerg_Lurker || t == BWAPI::UnitTypes::Zerg_Guardian || t == BWAPI::UnitTypes::Zerg_Sunken_Colony || t == BWAPI::UnitTypes::Zerg_Spore_Colony) { morphed = true; } setShortName(); }
/// Returns target attack priority. /// Returned value must be greater than 0 int VultureManagerExt::getAttackPriority(BWAPI::Unit * selectedUnit, BWAPI::Unit * target) { BWAPI::UnitType selectedUnitType = selectedUnit->getType(); BWAPI::UnitType targetType = target->getType(); bool canAttackUs = targetType.groundWeapon() != BWAPI::WeaponTypes::None; int selectedUnitWeaponRange = selectedUnitType.groundWeapon().maxRange(); // 160, Concussive int targetWeaponRange = targetType.groundWeapon().maxRange(); // Larvas are low priority targets if (targetType == BWAPI::UnitTypes::Zerg_Larva || targetType == BWAPI::UnitTypes::Protoss_Interceptor) { return 1; } else if (targetType == BWAPI::UnitTypes::Protoss_Pylon) { return 3; } else if ((targetType.isBuilding()) && !(targetType.canAttack())) { return 2; } else if (targetType == BWAPI::UnitTypes::Protoss_Photon_Cannon) { return 4; } // Templars are extremely dangerous to bio units and should be eliminated asap. else if (targetType == BWAPI::UnitTypes::Protoss_High_Templar || targetType == BWAPI::UnitTypes::Terran_Medic) { return selectedUnitWeaponRange + 10; } // Faster than Marine (without Stimpack) else if ((targetType.topSpeed() >= selectedUnitType.topSpeed()) || ((targetType == BWAPI::UnitTypes::Protoss_Zealot) && (BWAPI::Broodwar->enemy()->getUpgradeLevel(BWAPI::UpgradeTypes::Leg_Enhancements) > 0))) { return selectedUnitWeaponRange; // return 160 } // Slower than Vulture else { int priority = selectedUnitWeaponRange - targetWeaponRange; if (priority <= 0) { priority = 1; } return priority; } }
bool MorphManager::morph(BWAPI::UnitType type) { //morph order starts here //we only accept buildings that are made from other buildings //and units that are made from other units //fix: we should check to make sure the type is not an addon if (type.isBuilding()!=type.whatBuilds().first->isBuilding()) return false; morphQueues[*type.whatBuilds().first].push_back(type); plannedCount[type]++; return true; }
bool ConstructionManager::build(BWAPI::UnitType type, BWAPI::TilePosition goalPosition) { //build order starts here if (!type.isBuilding()) return false; //we only accept buildings Building newBuilding; newBuilding.type = type; newBuilding.goalPosition = goalPosition; newBuilding.tilePosition = BWAPI::TilePositions::None; newBuilding.builderUnit = NULL; //builder not picked yet newBuilding.buildingUnit = NULL; //building does not exist yet newBuilding.position = BWAPI::Positions::None; //no position yet newBuilding.lastOrderFrame = 0; newBuilding.started = false; //not started yet plannedCount[type]++; //increment planned count for this type of unit this->incompleteBuildings.push_back(newBuilding); return true; }
bool isSupportedUnitType(const BWAPI::UnitType & type) { if (type == BWAPI::UnitTypes::None || type == BWAPI::UnitTypes::Unknown) { return false; } if (type == BWAPI::UnitTypes::Protoss_Corsair || type == BWAPI::UnitTypes::Zerg_Devourer || type == BWAPI::UnitTypes::Zerg_Scourge || type == BWAPI::UnitTypes::Terran_Valkyrie) { return false; } if (type.isBuilding() && !(type == BWAPI::UnitTypes::Protoss_Photon_Cannon || type == BWAPI::UnitTypes::Zerg_Sunken_Colony || type == BWAPI::UnitTypes::Terran_Missile_Turret)) { return false; } if (type.isSpellcaster()) { return false; } // Don't support units loading other units yet if (type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine || type == BWAPI::UnitTypes::Protoss_Carrier || type == BWAPI::UnitTypes::Protoss_Interceptor || type == BWAPI::UnitTypes::Protoss_Reaver || type == BWAPI::UnitTypes::Protoss_Scarab || type == BWAPI::UnitTypes::Zerg_Broodling) { return false; } return true; }
void checkSupportedUnitType(const BWAPI::UnitType & type) { if (type == BWAPI::UnitTypes::None || type == BWAPI::UnitTypes::Unknown) { System::FatalError("Unknown unit type in experiment file, not supported"); } if (type == BWAPI::UnitTypes::Protoss_Corsair || type == BWAPI::UnitTypes::Zerg_Devourer || type == BWAPI::UnitTypes::Zerg_Scourge || type == BWAPI::UnitTypes::Terran_Valkyrie) { System::FatalError("Units with just air weapons currently not supported correctly: " + type.getName()); } if (type.isBuilding() && !(type == BWAPI::UnitTypes::Protoss_Photon_Cannon || type == BWAPI::UnitTypes::Zerg_Sunken_Colony || type == BWAPI::UnitTypes::Terran_Missile_Turret)) { System::FatalError("Non-attacking buildings not currently supported: " + type.getName()); } if (type.isSpellcaster()) { System::FatalError("Spell casting units not currently supported: " + type.getName()); } // Don't support units loading other units yet if (type == BWAPI::UnitTypes::Terran_Vulture_Spider_Mine || type == BWAPI::UnitTypes::Protoss_Carrier || type == BWAPI::UnitTypes::Protoss_Interceptor || type == BWAPI::UnitTypes::Protoss_Reaver || type == BWAPI::UnitTypes::Protoss_Scarab || type == BWAPI::UnitTypes::Zerg_Broodling) { System::FatalError("Units which have unit projectiles not supported: " + type.getName()); } }
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()); } } }
// returns an ActionSet of prerequisites for a given action ActionSet calculatePrerequisites(StarcraftAction & action) { ActionSet pre; if (DEBUG_StarcraftData) { printf("DEBUG: Hello\n"); printf("DEBUG: %d \t%s \t%s\n", getAction(action), action.getName().c_str(), actions[getAction(action)].getName().c_str()); } // if it's a UnitType if (action.getType() == StarcraftAction::UnitType) { std::map<BWAPI::UnitType, int> requiredUnits = action.getUnitType().requiredUnits(); BWAPI::UnitType actionType = action.getUnitType(); // if it's a protoss building that isn't a Nexus or Assimilator, we need a pylon (indirectly) if (actionType.getRace() == BWAPI::Races::Protoss && actionType.isBuilding() && !actionType.isResourceDepot() && !(actionType == BWAPI::UnitTypes::Protoss_Pylon) && !(actionType == BWAPI::UnitTypes::Protoss_Assimilator)) { pre.add(getAction(BWAPI::UnitTypes::Protoss_Pylon)); } // for each of the required UnitTypes for (std::map<BWAPI::UnitType, int>::iterator unitIt = requiredUnits.begin(); unitIt != requiredUnits.end(); unitIt++) { if (DEBUG_StarcraftData) printf("\tPRE: %s\n", unitIt->first.getName().c_str()); BWAPI::UnitType type = unitIt->first; // add the action to the ActionSet if it is not a larva if (type != BWAPI::UnitTypes::Zerg_Larva) { //printf("\t\tAdding %s\n", type.getName().c_str()); pre.add(getAction(type)); } } // if there is a TechType required if (action.getUnitType().requiredTech() != BWAPI::TechTypes::None) { if (DEBUG_StarcraftData) printf("\tPRE: %s\n", action.getUnitType().requiredTech().getName().c_str()); // add it to the ActionSet pre.add(getAction(action.getUnitType().requiredTech())); } } // if it's a TechType if (action.getType() == StarcraftAction::TechType) { if (action.getTechType().whatResearches() != BWAPI::UnitTypes::None) { if (DEBUG_StarcraftData) printf("\tPRE: %s\n", action.getTechType().whatResearches().getName().c_str()); // add what researches it pre.add(getAction(action.getTechType().whatResearches())); } } // if it's an UpgradeType if (action.getType() == StarcraftAction::UpgradeType) { if (action.getUpgradeType().whatUpgrades() != BWAPI::UnitTypes::None) { if (DEBUG_StarcraftData) printf("\tPRE: %s\n", action.getUpgradeType().whatUpgrades().getName().c_str()); // add what upgrades it pre.add(getAction(action.getUpgradeType().whatUpgrades())); } } //printf("Finish Prerequisites\n"); return pre; }
/// Returns target attack priority. /// Returned value must be greater than 0 int BattlecruiserManagerExt::getAttackPriority(BWAPI::Unit * selectedUnit, BWAPI::Unit * target) { BWAPI::UnitType selectedUnitType = selectedUnit->getType(); BWAPI::UnitType targetType = target->getType(); bool canAttackUs = targetType.airWeapon() != BWAPI::WeaponTypes::None; int selectedUnitWeaponRange = selectedUnitType.groundWeapon().maxRange(); // 160, Concussive int targetWeaponRange = targetType.groundWeapon().maxRange(); // Detectors are top priority but Photon Cannons are too strong if (targetType == BWAPI::UnitTypes::Protoss_Carrier) { useYamatoGun(selectedUnit, target); return 99; } else if (targetType.isDetector() && targetType != BWAPI::UnitTypes::Protoss_Photon_Cannon) { useYamatoGun(selectedUnit, target); return 100; } // Larvas are low priority targets else if (targetType == BWAPI::UnitTypes::Zerg_Larva || targetType == BWAPI::UnitTypes::Protoss_Interceptor) { return 1; } else if (targetType == BWAPI::UnitTypes::Protoss_Pylon) { return 3; } else if ((targetType.isBuilding()) && !(targetType.canAttack())) { return 2; } // Workers are priority over ground units and buildings else if (targetType.isWorker()) { return 4; } else if (isTurret(target)) { // Attack tower if in its weapon range // Otherwise attack something else if (target->isInWeaponRange(selectedUnit)) { return 5; } else { return 1; } } // Anti air units are top priority else if (canAttackUs) { return selectedUnitWeaponRange + 10; } else { return 1; } }