// calculate the recursive prerequisites for an Action, storing them in allPre // assumes that prerequisites have already been calculated void ActionTypeData::CalculateRecursivePrerequisites(PrerequisiteSet & allPre, const ActionTypeData & action) { PrerequisiteSet pre = action.getPrerequisites(); if (action.gasPrice() > 0) { if (action.raceID == Races::Protoss) { pre.add(ActionType(Races::Protoss, GetActionID(BWAPI::UnitTypes::Protoss_Assimilator))); } else if (action.raceID == Races::Terran) { pre.add(ActionType(Races::Terran, GetActionID(BWAPI::UnitTypes::Terran_Refinery))); } if (action.raceID == Races::Zerg) { pre.add(ActionType(Races::Zerg, GetActionID(BWAPI::UnitTypes::Zerg_Extractor))); } } for (size_t a(0); a < pre.size(); ++a) { const ActionType & actionType = pre.getActionType(a); if (!allPre.contains(actionType)) { allPre.add(actionType); CalculateRecursivePrerequisites(allPre, GetActionTypeData(actionType.getRace(), actionType.ID())); } } }
const PrerequisiteSet UnitData::getPrerequistesInProgress(const ActionType & action) const { PrerequisiteSet inProgress; for (size_t a(0); a<action.getPrerequisites().size(); ++a) { const ActionType & actionType = action.getPrerequisites().getActionType(a); if (getNumInProgress(actionType) > 0 && getNumCompleted(actionType) == 0) { inProgress.add(actionType); } } return inProgress; }
void Tools::CalculatePrerequisitesRequiredToBuild(const GameState & state, const PrerequisiteSet & needed, PrerequisiteSet & added) { // if anything needed gas and we don't have a refinery, we need to add one PrerequisiteSet allNeeded(needed); const ActionType & refinery = ActionTypes::GetRefinery(state.getRace()); if (!needed.contains(refinery) && (state.getUnitData().getNumCompleted(refinery) == 0) && !added.contains(refinery)) { for (size_t n(0); n<needed.size(); ++n) { if (needed.getActionType(n).gasPrice() > 0) { allNeeded.add(refinery); break; } } } for (size_t n(0); n<allNeeded.size(); ++n) { const ActionType & neededType = allNeeded.getActionType(n); // if we already have the needed type completed we can skip it if (added.contains(neededType) || state.getUnitData().getNumCompleted(neededType) > 0) { } // if we have the needed type in progress we can add that time else if (state.getUnitData().getNumInProgress(neededType) > 0) { //added.add(neededType); } // otherwise we need to recurse on the needed type to build its prerequisites else { added.add(neededType); CalculatePrerequisitesRequiredToBuild(state, neededType.getPrerequisites(), added); } } }
// returns an PrerequisiteSet of prerequisites for a given action PrerequisiteSet ActionTypeData::CalculatePrerequisites(const ActionTypeData & action) { PrerequisiteSet pre; // if it's a UnitType if (action.getType() == ActionTypeData::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(ActionType(Races::Protoss, GetActionID(BWAPI::UnitTypes::Protoss_Pylon)), 1); } // 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; int count = unitIt->second; // add the action to the PrerequisiteSet if it is not a larva if (type != BWAPI::UnitTypes::Zerg_Larva) { //printf("\t\tAdding %s\n", type.getName().c_str()); pre.add(ActionType(action.getRaceID(), GetActionID(type)), count); } } // 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()); BWAPI::TechType required = action.getUnitType().requiredTech(); // add it to the PrerequisiteSet pre.add(ActionType(action.getRaceID(), GetActionID(required)), 1); } } // if it's a TechType if (action.getType() == ActionTypeData::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(ActionType(action.getRaceID(), GetActionID(action.getTechType().whatResearches())), 1); } } // if it's an UpgradeType if (action.getType() == ActionTypeData::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(ActionType(action.getRaceID(), GetActionID(action.getUpgradeType().whatUpgrades())), 1); } } //printf("Finish Prerequisites\n"); return pre; }