diff --git a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
index 5433b6c..913bcbf 100644
--- a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
+++ b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
@@ -3,53 +3,6 @@ using CounterDrone.Core.Models;
namespace CounterDrone.Core.Algorithms
{
- /// 威胁画像
- public class ThreatProfile
- {
- public CombatScene Environment { get; set; } = new();
- public List Targets { get; set; } = new();
- public RoutePlan Route { get; set; } = new();
- public List Waypoints { get; set; } = new();
- public List ControlZones { get; set; } = new();
- /// 偏好平台类型(null = 算法自行决定,当前默认地基)
- public PlatformType? PreferredPlatformType { get; set; }
- }
-
- /// 防御推荐方案
- public class DefenseRecommendation
- {
- public DefenseSolution Best { get; set; } = new();
- public DefenseSolution Critical { get; set; } = new();
- }
-
- /// 单套防御方案
- public class DefenseSolution
- {
- public AerosolType RecommendedAerosolType { get; set; }
- public string AerosolRationale { get; set; } = string.Empty;
- public CloudDispersal RecommendedCloud { get; set; } = new();
-
- public List Platforms { get; set; } = new();
- public List Detections { get; set; } = new();
-
- public float InterceptProbability { get; set; }
- public string SummaryRationale { get; set; } = string.Empty;
-
- public List FireSchedule { get; set; } = new();
-
- /// 此方案占用的平台起始索引(多编队合并用)
- public int PlatformOffset { get; set; }
- }
-
- /// 多编队推荐结果
- public class MultiGroupRecommendation
- {
- /// 每组的独立方案
- public List GroupSolutions { get; set; } = new();
- /// 合并后的总发射计划
- public List MergedFireSchedule { get; set; } = new();
- }
-
/// 火力单元(完整的武器系统)
public class FireUnit
{
@@ -121,47 +74,17 @@ namespace CounterDrone.Core.Algorithms
}
}
- public class RecommendedPlatform
- {
- public PlatformType Type { get; set; }
- public Vector3 Position { get; set; }
- public int Quantity { get; set; }
- public int MunitionCount { get; set; }
- public float CoverageVolume { get; set; }
- public float Cooldown { get; set; } = 5f;
- public float MuzzleVelocity { get; set; } = 800f;
- /// 空基平台巡航速度 m/s
- public float CruiseSpeed { get; set; } = 55f;
- /// 空基平台投放高度 m
- public float ReleaseAltitude { get; set; }
- }
-
- public class RecommendedDetection
- {
- public Vector3 Position { get; set; }
- public float DetectionRadius { get; set; }
- public int Quantity { get; set; }
- }
-
/// 三维向量(纯 C#,不依赖 UnityEngine)
public struct Vector3
{
public float X, Y, Z;
public Vector3(float x, float y, float z) { X = x; Y = y; Z = z; }
-
- public static Vector3 operator +(Vector3 a, Vector3 b) => new(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
- public static Vector3 operator -(Vector3 a, Vector3 b) => new(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
- public static Vector3 operator *(Vector3 a, float s) => new(a.X * s, a.Y * s, a.Z * s);
- public float Length => (float)System.Math.Sqrt(X * X + Y * Y + Z * Z);
- public float DistanceTo(Vector3 other) => (this - other).Length;
}
/// 粒子渲染参数
public class ParticleParams
{
- public float EmitRate { get; set; } = 100;
public float Opacity { get; set; } = 1.0f;
- public string ColorHex { get; set; } = "#FFFFFF";
public float SizeMultiplier { get; set; } = 1.0f;
}
@@ -184,10 +107,7 @@ namespace CounterDrone.Core.Algorithms
public FireUnit Unit { get; set; } = null!;
public AerosolType AmmoType { get; set; }
public float EarliestInterceptTime { get; set; }
- public float CoverageDuration { get; set; }
public float KillProbability { get; set; }
- public float FlightTime { get; set; } // 弹药/平台飞行时间
- public float ShellFlightTime { get; set; } // 仅地基用
}
/// 单元分配:一个火力单元被分配给一个威胁的配置
diff --git a/src/CounterDrone.Core/Algorithms/CloudExpansionModel.cs b/src/CounterDrone.Core/Algorithms/CloudExpansionModel.cs
index 713b207..a007717 100644
--- a/src/CounterDrone.Core/Algorithms/CloudExpansionModel.cs
+++ b/src/CounterDrone.Core/Algorithms/CloudExpansionModel.cs
@@ -20,8 +20,6 @@ namespace CounterDrone.Core.Algorithms
/// Phase 2 结束时的有效半径(30s 湍流膨胀)
public float TurbulentRadius => RadiusAt(30f);
- /// Phase 2 边界时间
- public float Phase2Duration => 30f;
/// 湍流膨胀系数 k
public float TurbulentExpansionK => (float)_ammo.TurbulentExpansionK;
@@ -55,17 +53,6 @@ namespace CounterDrone.Core.Algorithms
return volume > 0.001f ? (float)_ammo.SourceStrength / volume : (float)_ammo.CoreDensity;
}
- /// 达到指定浓度所需时间(密度随膨胀下降,较晚时间密度更低)
- /// 浓度首次低于threshold的时间(s),如果不会低于则返回MaxDuration
- public float TimeToDensity(float threshold)
- {
- // 密度 ≈ SourceStrength / (4/3 π R³),随R增大而下降
- // 求R使得密度=threshold: R³ = SourceStrength / (threshold * 4π/3)
- float src = (float)_ammo.SourceStrength;
- float volume = src / Math.Max(threshold, 0.000001f);
- float r = (float)Math.Pow(volume * 3f / (4f * (float)Math.PI), 1f / 3f);
- return TimeToReach(r);
- }
/// 覆盖指定距离需要的云团数量
/// 需要覆盖的距离 (m)
diff --git a/src/CounterDrone.Core/Algorithms/DamageAssessment.cs b/src/CounterDrone.Core/Algorithms/DamageAssessment.cs
index ab6d39c..b44c6ae 100644
--- a/src/CounterDrone.Core/Algorithms/DamageAssessment.cs
+++ b/src/CounterDrone.Core/Algorithms/DamageAssessment.cs
@@ -3,7 +3,7 @@ using CounterDrone.Core.Models;
namespace CounterDrone.Core.Algorithms
{
- /// 毁伤评估——路径积分计算无人机穿过云团的暴露时间
+ /// 毁伤评估——路径积分计算无人机穿过云团的路径长度(米),用于换算暴露时间
public static class DamageAssessment
{
/// 线段 (p1→p2) 在球体内的长度,换算为路径长度 (m)
diff --git a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs b/src/CounterDrone.Core/Algorithms/DefensePlanner.cs
similarity index 97%
rename from src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs
rename to src/CounterDrone.Core/Algorithms/DefensePlanner.cs
index 22c8ac2..593954e 100644
--- a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs
+++ b/src/CounterDrone.Core/Algorithms/DefensePlanner.cs
@@ -5,15 +5,15 @@ using CounterDrone.Core.Models;
namespace CounterDrone.Core.Algorithms
{
- /// 默认防御规划器 — 五步流水线,全部调用与引擎共享的物理工具类
- public class DefaultDefensePlanner : IDefensePlanner
+ /// 防御规划器 — 五步流水线,全部调用与引擎共享的物理工具类
+ public class DefensePlanner : IDefensePlanner
{
private readonly List _ammoCatalog;
private readonly IDamageModel _damageModel;
private readonly PlannerConfig _config;
- public DefaultDefensePlanner(List ammoCatalog, PlannerConfig config,
- IDamageModel damageModel = null)
+ public DefensePlanner(List ammoCatalog, PlannerConfig config,
+ IDamageModel? damageModel = null)
{
_ammoCatalog = ammoCatalog ?? throw new ArgumentNullException(nameof(ammoCatalog));
_config = config ?? throw new ArgumentNullException(nameof(config));
@@ -290,10 +290,7 @@ namespace CounterDrone.Core.Algorithms
Unit = unit,
AmmoType = ammoType,
EarliestInterceptTime = interceptTime,
- CoverageDuration = effectiveR * 2f,
KillProbability = prob,
- FlightTime = shellTime,
- ShellFlightTime = shellTime,
};
}
@@ -324,10 +321,7 @@ namespace CounterDrone.Core.Algorithms
Unit = unit,
AmmoType = ammoType,
EarliestInterceptTime = interceptTime,
- CoverageDuration = effectiveR * 2f,
KillProbability = prob,
- FlightTime = totalTime,
- ShellFlightTime = fallTime,
};
}
diff --git a/src/CounterDrone.Core/Algorithms/Kinematics.cs b/src/CounterDrone.Core/Algorithms/Kinematics.cs
index 9528f88..d9421d5 100644
--- a/src/CounterDrone.Core/Algorithms/Kinematics.cs
+++ b/src/CounterDrone.Core/Algorithms/Kinematics.cs
@@ -55,12 +55,6 @@ namespace CounterDrone.Core.Algorithms
return range / (muzzleVelocity * cosAngle);
}
- /// 炮弹飞行时间:抛物线轨迹到目标点的时间(自动求解发射角,下行段命中)
- public static float EstimatedShellTime(float horizontalDist, float muzzleVelocity)
- {
- return ParabolicShellTime(horizontalDist, 0f, muzzleVelocity);
- }
-
/// 抛物线飞行时间:解 tan(θ) 二次方程求到达 (horizontalDist, heightDiff) 的时间
public static float ParabolicShellTime(float horizontalDist, float heightDiff, float muzzleVelocity)
{
@@ -232,16 +226,6 @@ namespace CounterDrone.Core.Algorithms
var denom = (float)Math.Pow(2f * (float)Math.PI, 1.5f) * sigmaY * sigmaY * sigmaZ;
return denom > 0.001f ? sourceStrength / denom : 0f;
}
-
- /// 高斯烟团某点浓度 C(x,y,z) — 简化:相对中心的偏移
- public static float GaussianConcentration(float q, float sx, float sy, float sz, float offsetY, float offsetZ)
- {
- var norm = q / ((float)Math.Pow(2f * (float)Math.PI, 1.5f) * sx * sy * sz);
- var ey = (float)Math.Exp(-0.5f * offsetY * offsetY / (sy * sy));
- var ez = (float)Math.Exp(-0.5f * offsetZ * offsetZ / (sz * sz));
- var ezr = (float)Math.Exp(-0.5f * offsetZ * offsetZ / (sz * sz));
- return norm * ey * (ez + ezr);
- }
public static bool PointInPolygon(float px, float pz, ReadOnlySpan<(float X, float Z)> vertices)
{
if (vertices.Length < 3) return false;
diff --git a/src/CounterDrone.Core/DefaultFireUnits.cs b/src/CounterDrone.Core/DefaultFireUnits.cs
index 19756d8..7afd5c6 100644
--- a/src/CounterDrone.Core/DefaultFireUnits.cs
+++ b/src/CounterDrone.Core/DefaultFireUnits.cs
@@ -4,7 +4,7 @@ namespace CounterDrone.Core
{
public static class DefaultFireUnits
{
- private static List _cache;
+ private static List? _cache;
public static List GetAll()
{
diff --git a/src/CounterDrone.Core/DefaultFormations.cs b/src/CounterDrone.Core/DefaultFormations.cs
deleted file mode 100644
index d0fb979..0000000
--- a/src/CounterDrone.Core/DefaultFormations.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Collections.Generic;
-
-namespace CounterDrone.Core
-{
- public static class DefaultFormations
- {
- private static List _cache;
-
- public static List GetAll()
- {
- if (_cache != null) return _cache;
- _cache = new List
- {
- new() { Id = "single", Name = "单机", FormationMode = 0, LateralCount = 1, LongitudinalCount = 1 },
- new() { Id = "line-abreast-3", Name = "3机横队", FormationMode = 1, LateralCount = 3, LongitudinalCount = 1,
- LateralSpacing = 50 },
- new() { Id = "line-abreast-5", Name = "5机横队", FormationMode = 1, LateralCount = 5, LongitudinalCount = 1,
- LateralSpacing = 50 },
- new() { Id = "column-3", Name = "3机纵队", FormationMode = 1, LateralCount = 1, LongitudinalCount = 3,
- LongitudinalSpacing = 100 },
- new() { Id = "box-2x2", Name = "2×2方队", FormationMode = 1, LateralCount = 2, LongitudinalCount = 2,
- LateralSpacing = 50, LongitudinalSpacing = 100 },
- new() { Id = "swarm-10", Name = "蜂群(10架)", FormationMode = 2, LateralCount = 10, LongitudinalCount = 1,
- LateralSpacing = 30 },
- };
- return _cache;
- }
-
- public static FormationTemplate GetById(string id) => GetAll().Find(t => t.Id == id);
- }
-
- public class FormationTemplate
- {
- public string Id { get; set; } = "";
- public string Name { get; set; } = "";
- public int FormationMode { get; set; }
- public int LateralCount { get; set; } = 1;
- public int LongitudinalCount { get; set; } = 1;
- public double LateralSpacing { get; set; }
- public double LongitudinalSpacing { get; set; }
- }
-}
diff --git a/src/CounterDrone.Core/Simulation/DroneEntity.cs b/src/CounterDrone.Core/Simulation/DroneEntity.cs
index 8ecf7e2..2240195 100644
--- a/src/CounterDrone.Core/Simulation/DroneEntity.cs
+++ b/src/CounterDrone.Core/Simulation/DroneEntity.cs
@@ -14,7 +14,6 @@ namespace CounterDrone.Core.Simulation
public float Wingspan { get; }
public float TypicalSpeed { get; }
public List Route { get; }
- public int CurrentWaypointIndex { get; private set; }
public float PosX { get; private set; }
public float PosY { get; private set; }
public float PosZ { get; private set; }
@@ -25,8 +24,6 @@ namespace CounterDrone.Core.Simulation
public float PrevX { get; private set; }
public float PrevY { get; private set; }
public float PrevZ { get; private set; }
- public float FormationOffsetX { get; set; }
- public float FormationOffsetY { get; set; }
/// 沿航路已飞行弧长(米),由 RouteGeometry 驱动
private float _traveledArc;
@@ -79,36 +76,19 @@ namespace CounterDrone.Core.Simulation
}
}
- private void ApplyFormationOffset(int latIdx, float latSpacing, int longIdx, float longSpacing, FormationMode mode)
- {
- if (latIdx == 0 && longIdx == 0) return;
- switch (mode)
- {
- case FormationMode.Formation:
- FormationOffsetY = latIdx * latSpacing;
- FormationOffsetX = -longIdx * longSpacing;
- break;
- case FormationMode.Swarm:
- var rng = new Random((latIdx + longIdx * 100) * 137);
- FormationOffsetX = (float)(rng.NextDouble() - 0.5) * latSpacing * 3;
- FormationOffsetY = (float)(rng.NextDouble() - 0.5) * latSpacing * 3;
- break;
- }
- }
-
public void SavePreviousPosition()
{
PrevX = PosX; PrevY = PosY; PrevZ = PosZ;
}
- public void Update(float deltaTime, float windSpeed, WindDirection windDir)
+ public void Update(float deltaTime)
{
if (Status != DroneStatus.Flying) return;
if (Route.Count == 0) return;
// 运动模型统一在 RouteGeometry:弧长推进 + 位置查询。
- // 无人机严格沿航路匀速飞行,不受风偏影响(风偏已移除,见风偏补偿说明)。
- // windSpeed/windDir 保留签名供未来飞控模型使用,当前不参与运动。
+ // 无人机严格按航路匀速飞行。无人机不受风偏影响(真实无人机有飞控修正航向),
+ // 但云团受风偏影响(见 SimulationEngine 毁伤判定的云团参考系修正)。
float totalLen = RouteGeometry.TotalLength(Route);
if (totalLen <= 0f)
{
diff --git a/src/CounterDrone.Core/Simulation/SimulationEngine.cs b/src/CounterDrone.Core/Simulation/SimulationEngine.cs
index 3ef9ba9..4141624 100644
--- a/src/CounterDrone.Core/Simulation/SimulationEngine.cs
+++ b/src/CounterDrone.Core/Simulation/SimulationEngine.cs
@@ -28,12 +28,12 @@ namespace CounterDrone.Core.Simulation
public IReadOnlyList Munitions => _munitions;
public IReadOnlyList Events => _allEvents;
- public event Action OnMunitionLaunched;
- public event Action OnCloudGenerated;
- public event Action OnDroneDestroyed;
- public event Action OnDroneReachedTarget;
- public event Action OnZoneIntruded;
- public event Action OnSimulationEnded;
+ public event Action? OnMunitionLaunched;
+ public event Action? OnCloudGenerated;
+ public event Action? OnDroneDestroyed;
+ public event Action? OnDroneReachedTarget;
+ public event Action? OnZoneIntruded;
+ public event Action? OnSimulationEnded;
private List _drones = new();
private List _platforms = new();
@@ -237,7 +237,7 @@ namespace CounterDrone.Core.Simulation
// 5. 无人机移动
foreach (var drone in _drones.Where(d => d.Status == DroneStatus.Flying))
{
- drone.Update(scaledDt, (float)_scene.WindSpeed, (WindDirection)_scene.WindDirection);
+ drone.Update(scaledDt);
if (drone.Status == DroneStatus.ReachedTarget)
{
OnDroneReachedTarget?.Invoke(drone);
@@ -257,14 +257,14 @@ namespace CounterDrone.Core.Simulation
{
float ccx = cloud.Dispersion.Center.X, ccy = cloud.Dispersion.Center.Y, ccz = cloud.Dispersion.Center.Z;
// 无人机线段换算到云团参考系:相对位置 = drone - cloud
- float inCloudTime = DamageAssessment.PathInSphere(
+ float inCloudDistance = DamageAssessment.PathInSphere(
drone.PrevX - (ccx - cloudDx), drone.PrevY - (ccy - cloudDy), drone.PrevZ - (ccz - cloudDz),
drone.PosX - ccx, drone.PosY - ccy, drone.PosZ - ccz,
0f, 0f, 0f,
cloud.Dispersion.EffectiveRadius);
- if (inCloudTime > 0 && cloud.Dispersion.CoreDensity >= (float)_ammoSpec.EffectiveConcentration)
+ if (inCloudDistance > 0 && cloud.Dispersion.CoreDensity >= (float)_ammoSpec.EffectiveConcentration)
{
- float exposureIncrement = inCloudTime / (drone.TypicalSpeed / 3.6f);
+ float exposureIncrement = inCloudDistance / (drone.TypicalSpeed / 3.6f);
drone.ExposureTime += exposureIncrement;
var dmg = _damageModel.CalculateDamage(drone.TargetType, drone.PowerType, cloud.AerosolType, cloud.Dispersion.CoreDensity, drone.ExposureTime, exposureIncrement);
drone.ApplyDamage(dmg);
diff --git a/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll b/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll
index 34d7ca7..5e2c73c 100644
Binary files a/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll and b/src/Unity/Assets/Plugins/CounterDrone.Core/CounterDrone.Core.dll differ
diff --git a/src/Unity/Assets/Scripts/Managers/ManagerVerification.cs b/src/Unity/Assets/Scripts/Managers/ManagerVerification.cs
index 7faf40c..6a395bb 100644
--- a/src/Unity/Assets/Scripts/Managers/ManagerVerification.cs
+++ b/src/Unity/Assets/Scripts/Managers/ManagerVerification.cs
@@ -72,7 +72,7 @@ namespace CounterDrone.Unity
TotalMunitions = 3,
AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel },
});
- var result = new DefaultDefensePlanner(ammoCatalog, PlannerConfig.Load(paths)).Plan(fireUnits, new List { droneGroup }, detail.Scene);
+ var result = new DefensePlanner(ammoCatalog, PlannerConfig.Load(paths)).Plan(fireUnits, new List { droneGroup }, detail.Scene);
scenarioMgr.SaveCloud(taskId, new CloudDispersal
{
PositionX = (droneGroup.Waypoints[0].PosX + droneGroup.Waypoints[^1].PosX) / 2,
diff --git a/src/Unity/Assets/Scripts/Managers/SimulationBootstrap.cs b/src/Unity/Assets/Scripts/Managers/SimulationBootstrap.cs
index a459f71..e102a83 100644
--- a/src/Unity/Assets/Scripts/Managers/SimulationBootstrap.cs
+++ b/src/Unity/Assets/Scripts/Managers/SimulationBootstrap.cs
@@ -67,7 +67,7 @@ namespace CounterDrone.Unity
// 推荐方案
var detail = scenario.GetTaskDetail(taskId);
var ammoCatalog = db.Table().ToList();
- var planner = new DefaultDefensePlanner(ammoCatalog, PlannerConfig.Load(paths));
+ var planner = new DefensePlanner(ammoCatalog, PlannerConfig.Load(paths));
var droneGroup = new DroneGroup
{
GroupId = "default",
diff --git a/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs b/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs
index fcaa156..78ee901 100644
--- a/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs
+++ b/src/Unity/Assets/Scripts/Managers/SimulationRunner.cs
@@ -48,7 +48,7 @@ namespace CounterDrone.Unity
new RoutePlanRepository(_db), new WaypointRepository(_db));
_frameStore = new FrameDataStore(_paths);
- _engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefaultDefensePlanner(DefaultAmmunition.GetAll(), PlannerConfig.Load(_paths)));
+ _engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefensePlanner(DefaultAmmunition.GetAll(), PlannerConfig.Load(_paths)));
}
public void LoadAndStart(string taskId)
diff --git a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs
index 94af12c..81bb3d6 100644
--- a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs
@@ -59,7 +59,7 @@ namespace CounterDrone.Core.Tests
private PlannerResult Plan(List units, DroneGroup threat,
CombatScene? env = null)
- => new DefaultDefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(units, new() { threat }, env ?? new CombatScene());
+ => new DefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(units, new() { threat }, env ?? new CombatScene());
// ═══════════════════════════════════════
// 威胁排序
@@ -233,7 +233,7 @@ namespace CounterDrone.Core.Tests
[Fact]
public void Allocation_MultiUnit_PoolsChannels()
{
- var result = new DefaultDefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(
+ var result = new DefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(
new() { MakeGroundUnit("u0", 5000), MakeGroundUnit("u1", 5100) },
new() { MakeThreat(speed: 200) }, new CombatScene());
Assert.True(result.Best.ThreatsEngaged == 1);
@@ -259,8 +259,8 @@ namespace CounterDrone.Core.Tests
// 边界
// ═══════════════════════════════════════
- [Fact] public void Edge_NoUnits_Unengaged() => Assert.Equal(1, new DefaultDefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(new(), new() { MakeThreat() }, new CombatScene()).Best.ThreatsUnengaged);
- [Fact] public void Edge_NoThreats_Empty() => Assert.Equal(0, new DefaultDefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(new() { MakeGroundUnit("u0", 5000) }, new(), new CombatScene()).Best.ThreatsEngaged);
+ [Fact] public void Edge_NoUnits_Unengaged() => Assert.Equal(1, new DefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(new(), new() { MakeThreat() }, new CombatScene()).Best.ThreatsUnengaged);
+ [Fact] public void Edge_NoThreats_Empty() => Assert.Equal(0, new DefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(new() { MakeGroundUnit("u0", 5000) }, new(), new CombatScene()).Best.ThreatsEngaged);
[Fact]
public void Edge_OutOfRange_Ground()
@@ -293,7 +293,7 @@ namespace CounterDrone.Core.Tests
{
var a = MakeThreat(PowerType.Piston, 120); a.GroupId = "g0";
var b = MakeThreat(PowerType.Jet, 300); b.GroupId = "g1";
- var result = new DefaultDefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(
+ var result = new DefensePlanner(TestAmmo, TestPlannerConfig.Instance).Plan(
new() { MakeGroundUnit("u0", 5000), MakeGroundUnit("u1", 5100) },
new() { a, b }, new CombatScene());
Assert.Equal(2, result.Best.ThreatsEngaged);
diff --git a/test/unit/CounterDrone.Core.Tests/DroneEntityTests.cs b/test/unit/CounterDrone.Core.Tests/DroneEntityTests.cs
index 748736e..9f19c51 100644
--- a/test/unit/CounterDrone.Core.Tests/DroneEntityTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/DroneEntityTests.cs
@@ -44,7 +44,7 @@ namespace CounterDrone.Core.Tests
var drone = new DroneEntity("d1", "g1", CreateConfig(),
CreateRoute(0, 1000, 300, 120), 0, 50, 0, 0, FormationMode.Single);
float prevX = drone.PosX;
- drone.Update(1f, 0, WindDirection.N);
+ drone.Update(1f);
Assert.True(drone.PosX > prevX);
}
@@ -53,7 +53,7 @@ namespace CounterDrone.Core.Tests
{
var drone = new DroneEntity("d1", "g1", CreateConfig(360),
CreateRoute(0, 100, 300, 360), 0, 50, 0, 0, FormationMode.Single);
- drone.Update(2f, 0, WindDirection.N);
+ drone.Update(2f);
Assert.Equal(DroneStatus.ReachedTarget, drone.Status);
}
@@ -140,25 +140,25 @@ namespace CounterDrone.Core.Tests
0, 0, 0, 0, FormationMode.Single);
// 推进到第一段中点(弧长 50):应在 X=50, Z=0
- drone.Update(50f / (60f / 3.6f), 0, WindDirection.N);
+ drone.Update(50f / (60f / 3.6f));
Assert.Equal(50f, drone.PosX, 1);
Assert.Equal(0f, drone.PosZ, 1);
Assert.Equal(DroneStatus.Flying, drone.Status);
// 推进到拐点(弧长 100):应在 X=100, Z=0
- drone.Update(50f / (60f / 3.6f), 0, WindDirection.N);
+ drone.Update(50f / (60f / 3.6f));
Assert.Equal(100f, drone.PosX, 1);
Assert.Equal(0f, drone.PosZ, 1);
Assert.Equal(DroneStatus.Flying, drone.Status);
// 推进到第二段中点(弧长 150):应在 X=100, Z=50
- drone.Update(50f / (60f / 3.6f), 0, WindDirection.N);
+ drone.Update(50f / (60f / 3.6f));
Assert.Equal(100f, drone.PosX, 1);
Assert.Equal(50f, drone.PosZ, 1);
Assert.Equal(DroneStatus.Flying, drone.Status);
// 推进到终点(弧长 200):应在 X=100, Z=100,状态 ReachedTarget
- drone.Update(50f / (60f / 3.6f), 0, WindDirection.N);
+ drone.Update(50f / (60f / 3.6f));
Assert.Equal(100f, drone.PosX, 1);
Assert.Equal(100f, drone.PosZ, 1);
Assert.Equal(DroneStatus.ReachedTarget, drone.Status);
diff --git a/test/unit/CounterDrone.Core.Tests/EdgeCaseTests.cs b/test/unit/CounterDrone.Core.Tests/EdgeCaseTests.cs
index 68cce2b..bcd447e 100644
--- a/test/unit/CounterDrone.Core.Tests/EdgeCaseTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/EdgeCaseTests.cs
@@ -65,7 +65,7 @@ namespace CounterDrone.Core.Tests
});
var engine = new SimulationEngine(_scenario, new FrameDataStore(new TestPathProvider(_testDir)),
- new DamageModelRouter(), new TestPathProvider(_testDir), new DefaultDefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
+ new DamageModelRouter(), new TestPathProvider(_testDir), new DefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
engine.Initialize(_taskId);
engine.TimeScale = 4f;
@@ -107,7 +107,7 @@ namespace CounterDrone.Core.Tests
});
var engine = new SimulationEngine(_scenario, new FrameDataStore(new TestPathProvider(_testDir)),
- new DamageModelRouter(), new TestPathProvider(_testDir), new DefaultDefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
+ new DamageModelRouter(), new TestPathProvider(_testDir), new DefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
engine.Initialize(_taskId);
engine.TimeScale = 4f;
@@ -148,7 +148,7 @@ namespace CounterDrone.Core.Tests
});
var engine = new SimulationEngine(_scenario, new FrameDataStore(new TestPathProvider(_testDir)),
- new DamageModelRouter(), new TestPathProvider(_testDir), new DefaultDefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
+ new DamageModelRouter(), new TestPathProvider(_testDir), new DefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
engine.Initialize(_taskId);
engine.TimeScale = 4f;
diff --git a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
index 2f2705d..9b25a8c 100644
--- a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
@@ -49,7 +49,7 @@ namespace CounterDrone.Core.Tests
private SimulationEngine RunSimulation(int maxTicks, float tickDt = 1f / 20f, float timeScale = 8f)
{
- var engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefaultDefensePlanner(_ammoCatalog, TestPlannerConfig.Instance));
+ var engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefensePlanner(_ammoCatalog, TestPlannerConfig.Instance));
engine.Initialize(_taskId);
engine.TimeScale = timeScale; // 8倍速加速
diff --git a/test/unit/CounterDrone.Core.Tests/SimulationEngineTests.cs b/test/unit/CounterDrone.Core.Tests/SimulationEngineTests.cs
index 66db8b5..cb873ef 100644
--- a/test/unit/CounterDrone.Core.Tests/SimulationEngineTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/SimulationEngineTests.cs
@@ -36,7 +36,7 @@ namespace CounterDrone.Core.Tests
new RoutePlanRepository(_mainDb), new WaypointRepository(_mainDb));
_engine = new SimulationEngine(_scenarioService, new FrameDataStore(paths),
- new DamageModelRouter(), paths, new DefaultDefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
+ new DamageModelRouter(), paths, new DefensePlanner(DefaultAmmunition.GetAll(), TestPlannerConfig.Instance));
}
public void Dispose()