feat: massive AI generation
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
|
||||
namespace SpaceGame.Api.Shared.AI;
|
||||
|
||||
public abstract class GoapAction<TState>
|
||||
{
|
||||
public abstract string Name { get; }
|
||||
public abstract float Cost { get; }
|
||||
public abstract bool CheckPreconditions(TState state);
|
||||
public abstract TState ApplyEffects(TState state);
|
||||
public abstract void Execute(SimulationEngine engine, SimulationWorld world, CommanderRuntime commander);
|
||||
}
|
||||
|
||||
public abstract class GoapGoal<TState>
|
||||
{
|
||||
public abstract string Name { get; }
|
||||
public abstract bool IsSatisfied(TState state);
|
||||
public abstract float ComputePriority(TState state, SimulationWorld world, CommanderRuntime commander);
|
||||
}
|
||||
|
||||
public sealed class GoapPlan<TState>
|
||||
{
|
||||
public static readonly GoapPlan<TState> Empty = new() { Actions = [], TotalCost = 0f };
|
||||
|
||||
public required IReadOnlyList<GoapAction<TState>> Actions { get; init; }
|
||||
public required float TotalCost { get; init; }
|
||||
public int CurrentStep { get; set; }
|
||||
|
||||
public GoapAction<TState>? CurrentAction => CurrentStep < Actions.Count ? Actions[CurrentStep] : null;
|
||||
public bool IsComplete => CurrentStep >= Actions.Count;
|
||||
public void Advance() => CurrentStep++;
|
||||
}
|
||||
|
||||
public sealed class GoapPlanner<TState>
|
||||
{
|
||||
private readonly Func<TState, TState> cloneState;
|
||||
|
||||
public GoapPlanner(Func<TState, TState> cloneState)
|
||||
{
|
||||
this.cloneState = cloneState;
|
||||
}
|
||||
|
||||
public GoapPlan<TState>? Plan(
|
||||
TState initialState,
|
||||
GoapGoal<TState> goal,
|
||||
IReadOnlyList<GoapAction<TState>> availableActions)
|
||||
{
|
||||
if (goal.IsSatisfied(initialState))
|
||||
{
|
||||
return GoapPlan<TState>.Empty;
|
||||
}
|
||||
|
||||
var openSet = new PriorityQueue<PlanNode, float>();
|
||||
openSet.Enqueue(new PlanNode(cloneState(initialState), [], 0f), 0f);
|
||||
|
||||
const int MaxIterations = 256;
|
||||
var iterations = 0;
|
||||
|
||||
while (openSet.Count > 0 && iterations++ < MaxIterations)
|
||||
{
|
||||
var current = openSet.Dequeue();
|
||||
|
||||
if (goal.IsSatisfied(current.State))
|
||||
{
|
||||
return new GoapPlan<TState>
|
||||
{
|
||||
Actions = current.Actions,
|
||||
TotalCost = current.Cost,
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var action in availableActions)
|
||||
{
|
||||
if (!action.CheckPreconditions(current.State))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var newState = action.ApplyEffects(cloneState(current.State));
|
||||
var newCost = current.Cost + action.Cost;
|
||||
var newActions = new List<GoapAction<TState>>(current.Actions) { action };
|
||||
openSet.Enqueue(new PlanNode(newState, newActions, newCost), newCost);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private sealed record PlanNode(
|
||||
TState State,
|
||||
IReadOnlyList<GoapAction<TState>> Actions,
|
||||
float Cost);
|
||||
}
|
||||
@@ -12,14 +12,47 @@ public enum WorkStatus
|
||||
{
|
||||
Pending,
|
||||
Active,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum OrderStatus
|
||||
{
|
||||
Queued,
|
||||
Accepted,
|
||||
Active,
|
||||
Completed,
|
||||
Cancelled,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanStatus
|
||||
{
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanStepStatus
|
||||
{
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanSourceKind
|
||||
{
|
||||
Rule,
|
||||
Order,
|
||||
DefaultBehavior,
|
||||
}
|
||||
|
||||
public enum ShipState
|
||||
@@ -49,22 +82,8 @@ public enum ShipState
|
||||
Blocked,
|
||||
Undocking,
|
||||
EngagingTarget,
|
||||
}
|
||||
|
||||
public enum ControllerTaskKind
|
||||
{
|
||||
Idle,
|
||||
Travel,
|
||||
Extract,
|
||||
Dock,
|
||||
Load,
|
||||
Unload,
|
||||
DeliverConstruction,
|
||||
BuildConstructionSite,
|
||||
AttackTarget,
|
||||
|
||||
ConstructModule,
|
||||
Undock,
|
||||
HoldingPosition,
|
||||
Fleeing,
|
||||
}
|
||||
|
||||
public static class SpaceLayerKinds
|
||||
@@ -95,37 +114,39 @@ public static class CommanderKind
|
||||
|
||||
public static class ShipTaskKinds
|
||||
{
|
||||
public const string Idle = "idle";
|
||||
public const string LocalMove = "local-move";
|
||||
public const string WarpToNode = "warp-to-node";
|
||||
public const string UseStargate = "use-stargate";
|
||||
public const string UseFtl = "use-ftl";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string Travel = "travel";
|
||||
public const string FollowTarget = "follow-target";
|
||||
public const string MineNode = "mine-node";
|
||||
public const string Dock = "dock";
|
||||
public const string Undock = "undock";
|
||||
public const string LoadCargo = "load-cargo";
|
||||
public const string UnloadCargo = "unload-cargo";
|
||||
|
||||
public const string MineNode = "mine-node";
|
||||
public const string HarvestGas = "harvest-gas";
|
||||
public const string DeliverToStation = "deliver-to-station";
|
||||
public const string ClaimLagrangePoint = "claim-lagrange-point";
|
||||
public const string TransferCargoToShip = "transfer-cargo-to-ship";
|
||||
public const string SalvageWreck = "salvage-wreck";
|
||||
public const string DeliverConstruction = "deliver-construction";
|
||||
public const string ConstructModule = "construct-module";
|
||||
public const string BuildConstructionSite = "build-construction-site";
|
||||
public const string EscortTarget = "escort-target";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string DefendCelestial = "defend-celestial";
|
||||
public const string Retreat = "retreat";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string Flee = "flee";
|
||||
public const string Wait = "wait";
|
||||
}
|
||||
|
||||
public static class ShipOrderKinds
|
||||
{
|
||||
public const string DirectMove = "direct-move";
|
||||
public const string TravelToNode = "travel-to-node";
|
||||
public const string Move = "move";
|
||||
public const string DockAtStation = "dock-at-station";
|
||||
public const string DeliverCargo = "deliver-cargo";
|
||||
public const string DockAndWait = "dock-and-wait";
|
||||
public const string FlyAndWait = "fly-and-wait";
|
||||
public const string FlyToObject = "fly-to-object";
|
||||
public const string FollowShip = "follow-ship";
|
||||
public const string TradeRoute = "trade-route";
|
||||
public const string MineAndDeliver = "mine-and-deliver";
|
||||
public const string BuildAtSite = "build-at-site";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string RepeatOrders = "repeat-orders";
|
||||
public const string Flee = "flee";
|
||||
}
|
||||
|
||||
public static class ClaimStateKinds
|
||||
@@ -174,18 +195,54 @@ public static class SimulationEnumMappings
|
||||
{
|
||||
WorkStatus.Pending => "pending",
|
||||
WorkStatus.Active => "active",
|
||||
WorkStatus.Blocked => "blocked",
|
||||
WorkStatus.Completed => "completed",
|
||||
WorkStatus.Failed => "failed",
|
||||
WorkStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this OrderStatus status) => status switch
|
||||
{
|
||||
OrderStatus.Queued => "queued",
|
||||
OrderStatus.Accepted => "accepted",
|
||||
OrderStatus.Active => "active",
|
||||
OrderStatus.Completed => "completed",
|
||||
OrderStatus.Cancelled => "cancelled",
|
||||
OrderStatus.Failed => "failed",
|
||||
OrderStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanStatus status) => status switch
|
||||
{
|
||||
AiPlanStatus.Planned => "planned",
|
||||
AiPlanStatus.Running => "running",
|
||||
AiPlanStatus.Blocked => "blocked",
|
||||
AiPlanStatus.Completed => "completed",
|
||||
AiPlanStatus.Failed => "failed",
|
||||
AiPlanStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanStepStatus status) => status switch
|
||||
{
|
||||
AiPlanStepStatus.Planned => "planned",
|
||||
AiPlanStepStatus.Running => "running",
|
||||
AiPlanStepStatus.Blocked => "blocked",
|
||||
AiPlanStepStatus.Completed => "completed",
|
||||
AiPlanStepStatus.Failed => "failed",
|
||||
AiPlanStepStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanSourceKind kind) => kind switch
|
||||
{
|
||||
AiPlanSourceKind.Rule => "rule",
|
||||
AiPlanSourceKind.Order => "order",
|
||||
AiPlanSourceKind.DefaultBehavior => "default-behavior",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this ShipState state) => state switch
|
||||
{
|
||||
ShipState.Idle => "idle",
|
||||
@@ -213,23 +270,8 @@ public static class SimulationEnumMappings
|
||||
ShipState.Blocked => "blocked",
|
||||
ShipState.Undocking => "undocking",
|
||||
ShipState.EngagingTarget => "engaging-target",
|
||||
ShipState.HoldingPosition => "holding-position",
|
||||
ShipState.Fleeing => "fleeing",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this ControllerTaskKind kind) => kind switch
|
||||
{
|
||||
ControllerTaskKind.Idle => "idle",
|
||||
ControllerTaskKind.Travel => "travel",
|
||||
ControllerTaskKind.Extract => "extract",
|
||||
ControllerTaskKind.Dock => "dock",
|
||||
ControllerTaskKind.Load => "load",
|
||||
ControllerTaskKind.Unload => "unload",
|
||||
ControllerTaskKind.DeliverConstruction => "deliver-construction",
|
||||
ControllerTaskKind.BuildConstructionSite => "build-construction-site",
|
||||
ControllerTaskKind.AttackTarget => "attack-target",
|
||||
|
||||
ControllerTaskKind.ConstructModule => "construct-module",
|
||||
ControllerTaskKind.Undock => "undock",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user