#include "game/ai/agent.h" namespace sots::ai { namespace { // Phases are numbered by their position in the original's body. Names are given only where a log // string or an already-named callee pins one; the rest stay empty on purpose, because a plausible // name for an unread phase is how a guess becomes a fact. std::vector BuildPhases() { std::vector p(kProcessTurnPhaseCount); for (int i = 0; i < kProcessTurnPhaseCount; ++i) { p[static_cast(i)].index = i; p[static_cast(i)].dead = PhaseRunsAfterSubmit(i); } auto at = [&p](int i) -> ProcessTurnPhase& { return p[static_cast(i)]; }; at(0).name = "log banner"; at(2).emits = PhaseEmission::Group5Gate; at(2).speciesRestricted = true; at(10).name = "survival outlook"; at(11).name = "survival outlook log"; at(12).name = "surrender roll"; // the AI's only chance draw in the turn body at(14).emits = PhaseEmission::Group4Gate; at(15).name = "set research rate"; at(15).emits = PhaseEmission::ResearchRate; at(18).name = "set research rate and target"; at(18).emits = PhaseEmission::ResearchTarget; at(kTaskListPhase).name = "task list"; at(kTaskListPhase).emits = PhaseEmission::TaskList; at(21).name = "system rates"; at(21).emits = PhaseEmission::SystemRates; at(23).emits = PhaseEmission::PopulationCmd; at(24).emits = PhaseEmission::FleetLayout; at(26).name = "new design"; at(26).emits = PhaseEmission::NewDesign; at(kSubmitPhase).name = "end turn"; at(kSubmitPhase).emits = PhaseEmission::Submit; at(32).name = "colonize"; at(32).emits = PhaseEmission::Colonize; return p; } } // namespace const std::vector& ProcessTurnPhases() { static const std::vector kPhases = BuildPhases(); return kPhases; } bool PhaseCanEmit(const ProcessTurnPhase& phase, sim::Species species) { if (phase.emits == PhaseEmission::None) return false; if (phase.emits == PhaseEmission::Submit) return false; if (phase.dead) return false; if (phase.speciesRestricted && species != kGroup5GatePhaseSpecies) return false; return true; } const std::vector& TaskWalkPasses() { static const std::vector kPasses = {static_cast(TaskPass::Reserve), static_cast(TaskPass::Fill)}; return kPasses; } void RunTaskList(std::vector& tasks, const TaskPriorityPolicy& policy, OrderClient& client, const TaskAction& action) { Rank(tasks, policy); for (int pass : TaskWalkPasses()) { client.EnterTaskPass(pass); for (const RankedTask& t : tasks) { if (action) action(t, pass, client); } client.LeaveTaskPass(); } } } // namespace sots::ai