using System.Collections.Generic;
using CounterDrone.Core;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using CounterDrone.Core.Repository;
using CounterDrone.Core.Services;
using CounterDrone.Core.Simulation;
using Xunit;
namespace CounterDrone.Core.Tests
{
/// 诊断 BuildFireSchedule 是否生成正确计划
public class FireScheduleDiagnostics
{
private static readonly List TestAmmo = new()
{
new AmmunitionSpec { AerosolType = (int)AerosolType.InertGas, InitialRadius = 50, CoreDensity = 1.0, DispersionRateBase = 5, MaxRadius = 200, MaxDuration = 60 },
new AmmunitionSpec { AerosolType = (int)AerosolType.ActiveMaterial, InitialRadius = 30, CoreDensity = 2.0, DispersionRateBase = 3, MaxRadius = 150, MaxDuration = 45 },
};
[Fact]
public void BuildFireSchedule_WithRecommendation_ProducesEvents()
{
// 模拟:活塞无人机威胁 → 算法推荐 → 发射计划
var threat = new ThreatProfile
{
Environment = new CombatScene { WindSpeed = 3 },
Targets = new List
{
new TargetConfig { TargetType = (int)TargetType.Piston, PowerType = (int)PowerType.Piston, Quantity = 1, TypicalSpeed = 200 },
},
Route = new RoutePlan { FormationMode = (int)FormationMode.Single },
Waypoints = new List
{
new Waypoint { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
new Waypoint { PosX = 20000, PosY = 500, PosZ = 0, Speed = 200 },
},
};
var rec = new DefaultDefenseAdvisor(TestAmmo).Recommend(threat);
// 检查推荐
Assert.True(rec.Best.RecommendedCloud.RecommendedTiming > 0,
$"推荐时机={rec.Best.RecommendedCloud.RecommendedTiming}");
Assert.NotEmpty(rec.Best.Platforms);
// 模拟持久化后读取
var cloud = rec.Best.RecommendedCloud;
var equips = new List();
foreach (var p in rec.Best.Platforms)
equips.Add(new EquipmentDeployment
{
EquipmentRole = (int)EquipmentRole.LaunchPlatform,
Quantity = p.Quantity,
PositionX = p.Position.X, PositionY = p.Position.Y, PositionZ = p.Position.Z,
AerosolType = (int)rec.Best.RecommendedAerosolType,
MunitionCount = p.MunitionCount, Cooldown = 5,
MuzzleVelocity = 800,
});
// 手动调用 BuildFireSchedule 同样的逻辑
var schedule = new List();
if (cloud.RecommendedTiming.HasValue && cloud.RecommendedTiming.Value > 0)
{
foreach (var p in equips)
{
var muzzleV = (float)(p.MuzzleVelocity ?? 800);
var dx = (float)cloud.PositionX - (float)p.PositionX;
var dz = (float)cloud.PositionZ - (float)p.PositionZ;
var dist = (float)System.Math.Sqrt(dx * dx + dz * dz);
var flightTime = dist / muzzleV;
var fireTime = (float)cloud.RecommendedTiming.Value - flightTime;
if (fireTime < 0) fireTime = 0.1f;
schedule.Add(new FireEvent
{
FireTime = fireTime,
PlatformIndex = 0,
TargetX = (float)cloud.PositionX,
TargetY = (float)cloud.PositionY,
TargetZ = (float)cloud.PositionZ,
MuzzleVelocity = muzzleV,
});
}
}
Assert.NotEmpty(schedule);
Assert.True(schedule[0].FireTime > 0);
Assert.Equal((float)cloud.PositionX, schedule[0].TargetX);
}
}
}