fix: stagger=roundInLane*speed 替代 ch*speed——通道展开为1后ch永远为0
- roundInLane = singleNeeded - laneNeeded[currentLane] - 跨度从 0.125s → 7.39s - Piston: 2/3 击毁
This commit is contained in:
parent
c5c1b79946
commit
0c9cdb7b82
@ -162,14 +162,12 @@ namespace CounterDrone.Core.Algorithms
|
|||||||
int remaining = remainingMunitions.GetValueOrDefault(c.Unit.Id, 0);
|
int remaining = remainingMunitions.GetValueOrDefault(c.Unit.Id, 0);
|
||||||
if (remaining <= 0) continue;
|
if (remaining <= 0) continue;
|
||||||
|
|
||||||
// 找下一个有需求的车道
|
|
||||||
while (currentLane < yLanes && laneNeeded[currentLane] <= 0) currentLane++;
|
while (currentLane < yLanes && laneNeeded[currentLane] <= 0) currentLane++;
|
||||||
if (currentLane >= yLanes) break;
|
if (currentLane >= yLanes) break;
|
||||||
|
|
||||||
int toTake = Math.Min(Math.Min(c.Unit.TotalChannels, remaining), laneNeeded[currentLane]);
|
int toTake = Math.Min(Math.Min(c.Unit.TotalChannels, remaining), laneNeeded[currentLane]);
|
||||||
if (toTake <= 0) continue;
|
if (toTake <= 0) continue;
|
||||||
|
|
||||||
// 此单元的所有弹药锁定同一个 Y 车道
|
|
||||||
int yLane = currentLane;
|
int yLane = currentLane;
|
||||||
var refEvt = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, 0, yLane, yLanes, formationWidth);
|
var refEvt = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, 0, yLane, yLanes, formationWidth);
|
||||||
float unitBaseTime = refEvt[0].FireTime;
|
float unitBaseTime = refEvt[0].FireTime;
|
||||||
@ -180,8 +178,10 @@ namespace CounterDrone.Core.Algorithms
|
|||||||
{
|
{
|
||||||
float offset = (eventIdx - (totalRoundsNeeded - 1) / 2f) * spacing;
|
float offset = (eventIdx - (totalRoundsNeeded - 1) / 2f) * spacing;
|
||||||
var fe = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, offset, yLane, yLanes, formationWidth);
|
var fe = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, offset, yLane, yLanes, formationWidth);
|
||||||
|
// 车道内序号 = 该车道已分配的弹药数
|
||||||
|
int roundInLane = singleNeeded - laneNeeded[currentLane];
|
||||||
foreach (var e in fe)
|
foreach (var e in fe)
|
||||||
e.FireTime = unitBaseTime + ch * stagger;
|
e.FireTime = unitBaseTime + roundInLane * stagger;
|
||||||
fevents.AddRange(fe);
|
fevents.AddRange(fe);
|
||||||
eventIdx++;
|
eventIdx++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,21 @@ namespace CounterDrone.Core.Tests
|
|||||||
var engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefaultDefensePlanner(_ammoCatalog));
|
var engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefaultDefensePlanner(_ammoCatalog));
|
||||||
|
|
||||||
engine.Initialize(_taskId);
|
engine.Initialize(_taskId);
|
||||||
|
|
||||||
|
// 诊断:检查 _fireSchedule 的时序
|
||||||
|
var fld = typeof(SimulationEngine).GetField("_fireSchedule", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
if (fld != null)
|
||||||
|
{
|
||||||
|
var schedule = fld.GetValue(engine) as System.Collections.IList;
|
||||||
|
if (schedule != null && schedule.Count > 0)
|
||||||
|
{
|
||||||
|
var ftimes = schedule.Cast<object>().Select(e => ((dynamic)e).FireTime).Cast<float>().ToList();
|
||||||
|
System.IO.File.WriteAllText(@"C:\Users\Tellme\Desktop\schedule_dump.txt",
|
||||||
|
$"count={schedule.Count} first={ftimes.Min():F3} last={ftimes.Max():F3} span={ftimes.Max()-ftimes.Min():F3}\n" +
|
||||||
|
string.Join("\n", ftimes.Select((t,i) => $"{t:F3}")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
engine.TimeScale = 8f; // 8倍速加速
|
engine.TimeScale = 8f; // 8倍速加速
|
||||||
for (int i = 0; i < maxTicks; i++)
|
for (int i = 0; i < maxTicks; i++)
|
||||||
{
|
{
|
||||||
@ -212,12 +227,15 @@ namespace CounterDrone.Core.Tests
|
|||||||
var launched = eng.Events.Count(e => e.Type == SimEventType.MunitionLaunched);
|
var launched = eng.Events.Count(e => e.Type == SimEventType.MunitionLaunched);
|
||||||
var clouds = eng.Events.Count(e => e.Type == SimEventType.CloudGenerated);
|
var clouds = eng.Events.Count(e => e.Type == SimEventType.CloudGenerated);
|
||||||
|
|
||||||
var msg = $"Piston: launched={launched} clouds={clouds} drones={eng.Drones.Count}";
|
var times = eng.Events.Where(e => e.Type == SimEventType.MunitionLaunched).Select(e => e.OccurredAt).OrderBy(t => t).ToList();
|
||||||
|
var timeInfo = $"times=[{times.First():F2}..{times.Last():F2}] span={times.Last()-times.First():F2}s";
|
||||||
|
|
||||||
|
var msg = $"Piston: launched={launched} clouds={clouds} drones={eng.Drones.Count} {timeInfo}";
|
||||||
foreach (var d in eng.Drones)
|
foreach (var d in eng.Drones)
|
||||||
msg += $" [{d.Status} hp={d.Hp:F2}]";
|
msg += $" [{d.Status} hp={d.Hp:F2}]";
|
||||||
VerifyAndExportReport(eng, eng.Drones[0]);
|
VerifyAndExportReport(eng, eng.Drones[0]);
|
||||||
Assert.True(launched > 0, msg);
|
Assert.True(launched > 0, msg);
|
||||||
Assert.All(eng.Drones, d => Assert.Equal(DroneStatus.Destroyed, d.Status));
|
Assert.True(eng.Drones.All(d => d.Status == DroneStatus.Destroyed), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════
|
// ═══════════════════════════════════════════════
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user