fix: multi-lane cloud offset used global index instead of per-lane index

Bug: offset = (eventIdx - (totalRoundsNeeded-1)/2) * spacing used global eventIdx across all lanes. For 3 lanes x 7 rounds = 21 clouds spread over 646m along route, making drones fly the whole chain sequentially.

Fix: offset = (roundInLane - (singleNeeded-1)/2) * spacing. Each lane independently distributes its 7 clouds over 194m, all lanes overlap on same route segment. Drones hit simultaneously.

Result: 3 drones destroyed at same time (t=91.6s, same X=5089), was sequential 87/91/96s. 193 tests pass.
This commit is contained in:
tian 2026-06-14 22:12:32 +08:00
parent 19780b54b9
commit d70d1f0bf8

View File

@ -142,7 +142,6 @@ namespace CounterDrone.Core.Algorithms
for (int l = 0; l < yLanes; l++) laneNeeded[l] = singleNeeded;
int currentLane = 0;
int roundsCollected = 0;
int eventIdx = 0;
var assignedUnits = new List<(FireUnit unit, int rounds, List<FireEvent> events)>();
foreach (var c in candidates.OrderBy(c => c.EarliestInterceptTime)
@ -170,19 +169,21 @@ namespace CounterDrone.Core.Algorithms
var fevents = new List<FireEvent>();
int unitIdx = fireUnits.IndexOf(c.Unit);
int baseRoundInLane = singleNeeded - laneNeeded[currentLane];
for (int ch = 0; ch < toTake; ch++)
{
float offset = (eventIdx - (totalRoundsNeeded - 1) / 2f) * spacing;
// offset 基于车道内发序(不是全局 eventIdx使每车道独立分布在同一航路段
// 多车道重叠覆盖而非沿航路连成长链
int roundInLane = baseRoundInLane + ch;
float offset = (roundInLane - (singleNeeded - 1) / 2f) * spacing;
var fe = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, offset, yLane, yLanes, formationWidth);
int baseRoundInLane = singleNeeded - laneNeeded[currentLane];
foreach (var e in fe)
{
e.FireTime = laneBaseTime[yLane] + (baseRoundInLane + ch) * stagger;
e.FireTime = laneBaseTime[yLane] + roundInLane * stagger;
// TargetX/Z 保留 GenerateFireEventsAt 算出的风偏补偿后抛撒点 cloudGenX/Z
e.PlatformIndex = unitIdx * c.Unit.TotalChannels + ch;
}
fevents.AddRange(fe);
eventIdx++;
}
assignedUnits.Add((c.Unit, toTake, fevents));