From 4411a452dc4eb3d3ffac15a7648518fbc3465f43 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Sat, 13 Jun 2026 09:50:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Quantity=20expand=20+=20PlatformIndex=20?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ApplyDefensePlan 展开 EquipmentDeployment.Quantity → 多个 FireUnit - Planner 分配后用 fireUnits.IndexOf 修正 PlatformIndex - 新增 FullPipeline_Piston_VerifiesRoundAllocation 验证 ≥8 发 - Piston 集成测试加入计划大小断言 --- .../Algorithms/DefaultDefensePlanner.cs | 7 ++++- .../DefensePlannerTests.cs | 19 +++++++++++++ .../FullPipelineTests.cs | 28 +++++++++++-------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs index 9f07258..5afd5e3 100644 --- a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs +++ b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs @@ -141,6 +141,11 @@ namespace CounterDrone.Core.Algorithms foreach (var (unit, rounds, fireEvents) in assignedUnits) { + // 平台索引 = 该单元在 fireUnits 列表中的位置 + int platIndex = fireUnits.IndexOf(unit); + // 修正 FireEvent 的平台索引 + foreach (var fe in fireEvents) fe.PlatformIndex = platIndex; + plan.Assignments.Add(new UnitAssignment { FireUnitId = unit.Id, @@ -405,7 +410,7 @@ namespace CounterDrone.Core.Algorithms events.Add(new FireEvent { FireTime = fireTime, - PlatformIndex = i % rounds, + PlatformIndex = 0, // 由调用方在分配后覆盖为正确索引 TargetX = tx, TargetY = mid.Y, TargetZ = tz, diff --git a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs index 274137c..df934b2 100644 --- a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs +++ b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs @@ -427,5 +427,24 @@ namespace CounterDrone.Core.Tests Assert.True(fe.FireTime < arrivalTime, $"FireTime={fe.FireTime:F0} >= ArrivalTime={arrivalTime:F0}")); } + [Fact] + public void FullPipeline_Piston_VerifiesRoundAllocation() + { + var units = MakeGroundUnits(8); + var threat = MakeThreat(PowerType.Piston, 200); // 集成测试同参数——速度设为 200 + threat.Waypoints.Clear(); + threat.Waypoints.Add(new Waypoint { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 }); + threat.Waypoints.Add(new Waypoint { PosX = 20000, PosY = 500, PosZ = 0, Speed = 200 }); + var planner = new DefaultDefensePlanner(TestAmmo); + var result = planner.Plan(units, new() { threat }, new CombatScene { WindSpeed = 3 }); + + Assert.True(result.Best.ThreatsEngaged == 1); + Assert.True(result.Best.MergedSchedule.Count >= 8, + $"只有 {result.Best.MergedSchedule.Count} 发,集成测试场景应>=8发"); + // 验证 PlatformIndex 有效 + Assert.All(result.Best.MergedSchedule, fe => + Assert.True(fe.PlatformIndex >= 0 && fe.PlatformIndex < units.Count, + $"PlatformIndex={fe.PlatformIndex} out of [0,{units.Count})")); + } } } diff --git a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs index a24b9bf..aef1d40 100644 --- a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs +++ b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs @@ -88,18 +88,22 @@ namespace CounterDrone.Core.Tests var idx = 0; foreach (var eq in detail.Equipment.Where(e => e.EquipmentRole == (int)EquipmentRole.LaunchPlatform)) { - fireUnits.Add(new FireUnit + int qty = Math.Max(1, eq.Quantity); + for (int i = 0; i < qty; i++) { - Id = $"u{idx++}", - Type = platType, - Position = new Vector3((float)eq.PositionX, (float)eq.PositionY, (float)eq.PositionZ), - CruiseSpeed = (float)(eq.CruiseSpeed ?? 55f), - ReleaseAltitude = (float)(eq.ReleaseAltitude ?? 0f), - MuzzleVelocity = (float)(eq.MuzzleVelocity ?? 800f), - TotalMunitions = eq.MunitionCount ?? 1, - AmmoTypes = new List { (AerosolType)(eq.AerosolType ?? 0) }, - Cooldown = (float)eq.Cooldown, - }); + fireUnits.Add(new FireUnit + { + Id = $"u{idx++}", + Type = platType, + Position = new Vector3((float)eq.PositionX + i * 50, (float)eq.PositionY, (float)eq.PositionZ), + CruiseSpeed = (float)(eq.CruiseSpeed ?? 55f), + ReleaseAltitude = (float)(eq.ReleaseAltitude ?? 0f), + MuzzleVelocity = (float)(eq.MuzzleVelocity ?? 800f), + TotalMunitions = eq.MunitionCount ?? 1, + AmmoTypes = new List { (AerosolType)(eq.AerosolType ?? 0) }, + Cooldown = (float)eq.Cooldown, + }); + } } // 如果没装备,生成默认的地面单元 @@ -298,6 +302,8 @@ namespace CounterDrone.Core.Tests var plan = ApplyDefensePlan(); Assert.True(plan.ThreatsEngaged > 0); Assert.NotEmpty(plan.MergedSchedule); + Assert.True(plan.MergedSchedule.Count >= 8, + $"Piston Planner 只生成了 {plan.MergedSchedule.Count} 发,预期 >= 8"); var eng = RunSimulation(8000);