Ejemplo n.º 1
0
const FrameCountType GameState::whenPrerequisitesReady(const ActionType & action) const
{
    if (action == ActionTypes::GetActionType("Protoss_Dark_Templar"))
    {
        int a = 6;
    }

    FrameCountType preReqReadyTime = _currentFrame;

    // if a building builds this action
    if (action.whatBuildsIsBuilding())
    {
        // get when the building / prereqs will be ready
        preReqReadyTime = whenBuildingPrereqReady(action);
    }
    // otherwise something else builds this action so we don't worry about buildings
    else
    {
        // if requirement in progress (and not already made), set when it will be finished
        PrerequisiteSet reqInProgress = _units.getPrerequistesInProgress(action);

        // if it's not empty, check when they will be done
        if (!reqInProgress.isEmpty())
        {
            preReqReadyTime = _units.getFinishTime(reqInProgress);
        }
    }

    return preReqReadyTime;
}
Ejemplo n.º 2
0
// 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()));
        }
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
const FrameCountType GameState::whenBuildingPrereqReady(const ActionType & action) const
{
    FrameCountType buildingAvailableTime(0);
    const ActionType & builder = action.whatBuildsActionType();

    BOSS_ASSERT(builder.isBuilding(), "The thing that builds this is not a building");

    bool buildingIsConstructed                  = _units.getBuildingData().canBuildEventually(action);//getNumCompleted(builder) > 0;
    bool buildingInProgress                     = _units.getNumInProgress(builder) > 0;
    FrameCountType constructedBuildingFreeTime  = std::numeric_limits<int>::max()-10;
    FrameCountType buildingInProgressFinishTime = std::numeric_limits<int>::max()-10;

    BOSS_ASSERT(buildingIsConstructed || (!action.requiresAddon() && buildingInProgress), "We will never be able to build action: %s", action.getName().c_str());
    
    if (buildingIsConstructed)
    {
        constructedBuildingFreeTime  = _currentFrame + _units.getBuildingData().getTimeUntilCanBuild(action);
    }
        
    if (!action.requiresAddon() && buildingInProgress)
    {
        buildingInProgressFinishTime = _units.getFinishTime(builder);
    }

    // this will give us when the building will be free to build this action
    buildingAvailableTime = std::min(constructedBuildingFreeTime, buildingInProgressFinishTime);

    // get all prerequisites currently in progress but do not have any completed
    PrerequisiteSet prereqInProgress = _units.getPrerequistesInProgress(action);

    // remove the specific builder from this list since we calculated that earlier
    prereqInProgress.remove(builder);

    //// if we actually have some prerequisites in progress other than the building
    if (!prereqInProgress.isEmpty())
    {
        // get the max time the earliest of each type will be finished in
        FrameCountType C = _units.getFinishTime(prereqInProgress);

        // take the maximum of this value and when the building was available
        buildingAvailableTime = (C > buildingAvailableTime) ? C : buildingAvailableTime;
    }
    
    return buildingAvailableTime;
}
Ejemplo n.º 5
0
FrameCountType Tools::GetLowerBound(const GameState & state, const BuildOrderSearchGoal & goal)
{
    PrerequisiteSet wanted;

    // add everything from the goal to the needed set
    for (size_t a(0); a < ActionTypes::GetAllActionTypes(state.getRace()).size(); ++a)
    {
        const ActionType & actionType = ActionTypes::GetActionType(state.getRace(), a);
        UnitCountType numCompleted = state.getUnitData().getNumTotal(actionType);
            
        if (goal.getGoal(actionType) > numCompleted)
        {
            wanted.addUnique(actionType);
        }
    }

    FrameCountType lowerBound = Tools::CalculatePrerequisitesLowerBound(state, wanted, 0);

    return lowerBound;
}
// recursively checks the tech tree of Action and sets each to have goalMax of 1
void DFBB_BuildOrderSmartSearch::recurseOverStrictDependencies(const ActionType & actionType)
{
    if (actionType.isResourceDepot() || actionType.isWorker() || actionType.isSupplyProvider() || actionType.isRefinery())
    {
        return;
    }

    PrerequisiteSet recursivePrerequisites = actionType.getRecursivePrerequisites();

    for (size_t a(0); a < recursivePrerequisites.size(); ++a)
    {
        const ActionType & actionType = recursivePrerequisites.getActionType(a);

        if (actionType.isResourceDepot() ||actionType.isWorker() || actionType.isSupplyProvider() || actionType.isRefinery())
        {
            continue;
        }

        _goal.setGoalMax(actionType, std::max((UnitCountType)1, _goal.getGoalMax(actionType)));
    }
}
Ejemplo n.º 7
0
const bool UnitData::hasPrerequisites(const PrerequisiteSet & required) const
{
    static const ActionType & Hatchery      = ActionTypes::GetActionType("Zerg_Hatchery");
    static const ActionType & Lair          = ActionTypes::GetActionType("Zerg_Lair");
    static const ActionType & Hive          = ActionTypes::GetActionType("Zerg_Hive");
    static const ActionType & Spire         = ActionTypes::GetActionType("Zerg_Spire");
    static const ActionType & GreaterSpire  = ActionTypes::GetActionType("Zerg_Greater_Spire");

    for (size_t a(0); a<required.size(); ++a)
    {
        const ActionType & type = required.getActionType(a);
        const size_t & req = required.getActionTypeCount(a);
        size_t have = getNumTotal(type);

        // special check for zerg moprhed buildings
        if (_race == Races::Zerg)
        {
            if (type == Hatchery)
            {
                have += getNumTotal(Lair);
                have += getNumTotal(Hive);
            }
            else if (type == Lair)
            {
                have += getNumTotal(Hive);
            }
            else if (type == Spire)
            {
                have += getNumTotal(GreaterSpire);
            }
        }

        if (have < req)
        {
            return false;
        }
    }

    return true;
}
Ejemplo n.º 8
0
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);
        }
    }
}
Ejemplo n.º 9
0
// returns the amount of time necessary to complete the longest chain of sequential prerequisites
FrameCountType Tools::CalculatePrerequisitesLowerBound(const GameState & state, const PrerequisiteSet & needed, FrameCountType timeSoFar, int depth)
{
    FrameCountType max = 0;
    for (size_t n(0); n<needed.size(); ++n)
    {
        const ActionType & neededType = needed.getActionType(n);
        FrameCountType thisActionTime = 0;

        // if we already have the needed type completed we can skip it
        if (state.getUnitData().getNumCompleted(neededType) > 0)
        {
            thisActionTime = timeSoFar;
        }
        // if we have the needed type in progress we can add that time
        else if (state.getUnitData().getNumInProgress(neededType) > 0)
        {
            thisActionTime = timeSoFar + state.getUnitData().getFinishTime(neededType) - state.getCurrentFrame();
        }
        // otherwise we need to recurse on the needed type to build its prerequisites
        else
        {
            /*for (int i=0; i<depth; ++i)
            {
                std::cout << "    ";
            }
            std::cout << neededType.getName() << " " << neededType.buildTime() << " " << timeSoFar << std::endl;*/
            thisActionTime = CalculatePrerequisitesLowerBound(state, neededType.getPrerequisites(), timeSoFar + neededType.buildTime(), depth + 1);
        }

        if (thisActionTime > max)
        {
            max = thisActionTime;
        }
    }

    return max;
}
Ejemplo n.º 10
0
BuildOrder Tools::GetNaiveBuildOrderAddWorkers(const GameState & state, const BuildOrderSearchGoal & goal, UnitCountType maxWorkers)
{
    PrerequisiteSet wanted;
    int minWorkers = 8;

    const ActionType & worker = ActionTypes::GetWorker(state.getRace());
    std::vector<size_t> buildOrderActionTypeCount(ActionTypes::GetAllActionTypes(state.getRace()).size(), 0);

    // add everything from the goal to the needed set
    for (size_t a(0); a < ActionTypes::GetAllActionTypes(state.getRace()).size(); ++a)
    {
        const ActionType & actionType = ActionTypes::GetActionType(state.getRace(), a);
        UnitCountType numCompleted = state.getUnitData().getNumTotal(actionType);
            
        if (goal.getGoal(actionType) > numCompleted)
        {
            wanted.addUnique(actionType);
        }
    }

    if (wanted.size() == 0)
    {
        return BuildOrder();
    }

    // Calculate which prerequisite units we need to build to achieve the units we want from the goal
    PrerequisiteSet requiredToBuild;
    CalculatePrerequisitesRequiredToBuild(state, wanted, requiredToBuild);

    // Add the required units to a preliminary build order
    BuildOrder buildOrder;
    for (size_t a(0); a < requiredToBuild.size(); ++a)
    {
        const ActionType & type = requiredToBuild.getActionType(a);
        buildOrder.add(type);
        buildOrderActionTypeCount[type.ID()]++;
    }

    // Add some workers to the build order if we don't have many, this usually gives a lower upper bound
    int requiredWorkers = minWorkers - state.getUnitData().getNumCompleted(ActionTypes::GetWorker(state.getRace()));
    while (requiredWorkers-- > 0)
    {
        buildOrder.add(worker);
        buildOrderActionTypeCount[worker.ID()]++;
    }

    // Add the goal units to the end of the build order 
    for (size_t a(0); a < ActionTypes::GetAllActionTypes(state.getRace()).size(); ++a)
    {
        const ActionType & actionType = ActionTypes::GetActionType(state.getRace(), a);
        int need = (int)goal.getGoal(actionType);
        int have = (int)state.getUnitData().getNumTotal(actionType);
        int numNeeded = need - have - buildOrderActionTypeCount[actionType.ID()]; 
            
        for (int i(0); i < numNeeded; ++i)
        {
            buildOrder.add(actionType);
        }
    }

    
    static const ActionType commandCenter = ActionTypes::GetActionType("Terran_Command_Center");
    static const ActionType factory = ActionTypes::GetActionType("Terran_Factory");
    static const ActionType starport = ActionTypes::GetActionType("Terran_Starport");
    static const ActionType scienceFacility = ActionTypes::GetActionType("Terran_Science_Facility");


    // Check to see if we have enough buildings for the required addons
    if (state.getRace() == Races::Terran)
    {
        int commandCenterAddons = 0;
        int factoryAddons = 0;
        int starportAddons = 0;
        int sciAddons = 0;

        int numCommandCenters = state.getUnitData().getNumTotal(commandCenter);
        int numFactories = state.getUnitData().getNumTotal(factory);
        int numStarports = state.getUnitData().getNumTotal(starport);
        int numSci = state.getUnitData().getNumTotal(scienceFacility);
        
        for (size_t a(0); a < buildOrder.size(); ++a)
        {
            const ActionType & actionType = buildOrder[a];

            if (actionType.isAddon())
            {
                if (actionType.whatBuildsActionType() == commandCenter)
                {
                    ++commandCenterAddons;
                }
                else if (actionType.whatBuildsActionType() == factory)
                {
                    ++factoryAddons;
                }
                else if (actionType.whatBuildsActionType() == starport)
                {
                    ++starportAddons;
                }
                else if (actionType.whatBuildsActionType() == scienceFacility)
                {
                    ++sciAddons;
                }
                else
                {
                    BOSS_ASSERT(false, "Addon has no builder: %s %s", actionType.getName().c_str(), actionType.whatBuildsActionType().getName().c_str());
                }
            }

            if (actionType == commandCenter)
            {
                ++numCommandCenters;
            }
            else if (actionType == factory)
            {
                ++numFactories;
            }
            else if (actionType == starport)
            {
                ++numStarports;
            }
            else if (actionType == scienceFacility)
            {
                ++numSci;
            }
        }

        // add the necessary buildings to make the addons
        for (int n(0); n < commandCenterAddons - numCommandCenters; ++n)
        {
            buildOrder.add(commandCenter);
        }

        for (int n(0); n < factoryAddons - numFactories; ++n)
        {
            buildOrder.add(factory);
        }

        for (int n(0); n < starportAddons - numStarports; ++n)
        {
            buildOrder.add(starport);
        }
        for (int n(0); n < sciAddons - numSci; ++n)
        {
            buildOrder.add(scienceFacility);
        }

    }

    // Bubble sort the build order so that prerequites always come before what requires them
    for (size_t i(0); i < buildOrder.size()-1; ++i)
    {
        for (size_t j(i+1); j < buildOrder.size(); ++j)
        {
            const PrerequisiteSet & recursivePre = buildOrder[i].getRecursivePrerequisites();

            if (recursivePre.contains(buildOrder[j]))
            {
                std::swap(buildOrder[i], buildOrder[j]);
            }
        }
    }

    // finish the build order with workers and supply
    BuildOrder finalBuildOrder;
    GameState currentState(state);
    size_t i = 0;
    while (i < buildOrder.size())
    {
        const ActionType & worker           = ActionTypes::GetWorker(currentState.getRace());
        const ActionType & supplyProvider   = ActionTypes::GetSupplyProvider(currentState.getRace());
        const ActionType & nextAction       = buildOrder[i];
        UnitCountType maxSupply             = currentState.getUnitData().getMaxSupply() + currentState.getUnitData().getSupplyInProgress();
        UnitCountType numWorkers            = currentState.getUnitData().getNumTotal(worker);
        UnitCountType currentSupply         = currentState.getUnitData().getCurrentSupply();

        if (numWorkers < 8)
        {
            finalBuildOrder.add(worker);
            currentState.doAction(worker);
            continue;
        }

        // insert a supply provider if we are behind
        int surplusSupply = maxSupply - currentSupply;
		if (surplusSupply < nextAction.supplyRequired() + 2)
		{
			try
			{
				BOSS_ASSERT(currentState.isLegal(supplyProvider), "supplyProvider should be legal");
				finalBuildOrder.add(supplyProvider);
				currentState.doAction(supplyProvider);
				continue;
			}
			catch (const Assert::BOSSException &)
			{
				break;
			}

		}

       
        FrameCountType whenWorkerReady      = currentState.whenCanPerform(worker);
        FrameCountType whennextActionReady  = currentState.whenCanPerform(nextAction);

        if ((numWorkers < maxWorkers) && (whenWorkerReady < whennextActionReady))
        {
			// check to see if we should insert a worker
			try
			{
				BOSS_ASSERT(currentState.isLegal(worker), "Worker should be legal");
				finalBuildOrder.add(worker);
				currentState.doAction(worker);
			}
			catch (const Assert::BOSSException &)
			{
			}
			continue;
		}
		else
		{
			ActionType testNextAction = buildOrder[i];
			BOSS_ASSERT(currentState.isLegal(nextAction), "nextAction should be legal");
			finalBuildOrder.add(nextAction);
			currentState.doAction(nextAction);
			++i;
		}
    }

    return finalBuildOrder;
}
Ejemplo n.º 11
0
// 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;
}