void CombatSearch_BestResponse::doSearch(const GameState & state, size_t depth) { if (timeLimitReached()) { throw BOSS_COMBATSEARCH_TIMEOUT; } _bestResponseData.update(_params.getInitialState(), state, _buildOrder); updateResults(state); if (isTerminalNode(state, depth)) { return; } ActionSet legalActions; generateLegalActions(state, legalActions, _params); for (UnitCountType a(0); a < legalActions.size(); ++a) { size_t ri = legalActions.size() - 1 - a; GameState child(state); child.doAction(legalActions[ri]); _buildOrder.add(legalActions[ri]); doSearch(child,depth+1); _buildOrder.pop_back(); } }
void DFBB_BuildOrderStackSearch::generateLegalActions(const GameState & state, ActionSet & legalActions) { legalActions.clear(); DFBB_BuildOrderSearchGoal & goal = _params.goal; const ActionType & worker = ActionTypes::GetWorker(state.getRace()); // add all legal relevant actions that are in the goal for (size_t a(0); a < _params.relevantActions.size(); ++a) { const ActionType & actionType = _params.relevantActions[a]; if (state.isLegal(actionType)) { // if there's none of this action in the goal it's not legal if (!goal.getGoal(actionType) && !goal.getGoalMax(actionType)) { continue; } // if we alread have more than the goal it's not legal if (goal.getGoal(actionType) && (state.getUnitData().getNumTotal(actionType) >= goal.getGoal(actionType))) { continue; } // if we already have more than the goal max it's not legal if (goal.getGoalMax(actionType) && (state.getUnitData().getNumTotal(actionType) >= goal.getGoalMax(actionType))) { continue; } legalActions.add(_params.relevantActions[a]); } } // don't make anything until we have 8 workers if (state.getUnitData().getNumTotal(worker) < 8) { legalActions.clear(); legalActions.add(worker); return; } // if we enabled the supply bounding flag if (_params.useSupplyBounding) { UnitCountType supplySurplus = state.getUnitData().getMaxSupply() + state.getUnitData().getSupplyInProgress() - state.getUnitData().getCurrentSupply(); UnitCountType threshold = (UnitCountType)(ActionTypes::GetSupplyProvider(state.getRace()).supplyProvided() * _params.supplyBoundingThreshold); if (supplySurplus >= threshold) { legalActions.remove(ActionTypes::GetSupplyProvider(state.getRace())); } } // if we enabled the always make workers flag, and workers are legal if (_params.useAlwaysMakeWorkers && legalActions.contains(worker)) { bool actionLegalBeforeWorker = false; ActionSet legalEqualWorker; FrameCountType workerReady = state.whenCanPerform(worker); for (size_t a(0); a < legalActions.size(); ++a) { const ActionType & actionType = legalActions[a]; const FrameCountType whenCanPerformAction = state.whenCanPerform(actionType); if (whenCanPerformAction < workerReady) { actionLegalBeforeWorker = true; break; } if ((whenCanPerformAction == workerReady) && (actionType.mineralPrice() == worker.mineralPrice())) { legalEqualWorker.add(actionType); } } if (actionLegalBeforeWorker) { legalActions.remove(worker); } else { legalActions = legalEqualWorker; } } }