Tests: the AI streams in both directions; sampling and admitting take nothing from the item stream, and each pilot's circuit is its own

Pins the survivors soul-ai-consumes-item-stream and soul-patrol-same-for-every-pilot of verdict s1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-18 00:54:01 +02:00
commit a899432d46
3 changed files with 38 additions and 0 deletions

View file

@ -339,6 +339,20 @@ public sealed class ConsumableAiTests : IDisposable
Assert.True(s.Zone.Agents.Last(a => ReferenceEquals(a.Ship, s.Agent)).Id > first, "a re-admitted pilot is a new id");
}
// Admitting a pilot takes nothing from the item stream: its patrol circuit is its own draw, so how pilots are chosen never
// moves what is minted next. Kills: the circuit drawn from ItemManager.Random.
[Fact]
public void AdmittingAPilotDrawsNothingFromTheItemStream()
{
var s = Build(carryOverdrive: true);
Assert.True(s.Zone.Remove(s.Agent));
s.Agent.Deactivate();
var items = s.Agent.ItemManager;
var before = items.Random;
s.Zone.Admit(s.Agent, piloted: true);
Assert.Equal(before.NextFloat(), items.Random.NextFloat());
}
// The production path for the optimum: a ship the zone admits as piloted derives it from its gun's live stats
// before it needs it, and re-derives it when its loadout changes. The gun's effective range is 500 and the
// heavy gun's is 800, so the optimum moves with the weapons it has now.

View file

@ -811,6 +811,13 @@ public sealed class FireControlPerWeaponTests : IDisposable
var cells = (Optimum(id, 0) - offset - min) / step;
Assert.True(MathF.Abs(cells - MathF.Round(cells)) < .01f, $"id {id}: optimum is {cells} steps from the pilot's own offset");
}
// The other direction: sampling the optimum takes nothing from the item stream, so how a pilot fights never moves
// what is minted next. Kills: an AI draw from ItemManager.Random.
var items = r.Shooter.ItemManager;
var before = items.Random;
Optimum(5, 0);
Assert.Equal(before.NextFloat(), items.Random.NextFloat());
}
// A round refused on a Range that fell between the trigger and the round is still free: the burst is paid

View file

@ -319,6 +319,23 @@ public sealed partial class RunStartTests
Assert.Equal(Places(plain), Places(disturbed));
}
// Each pilot's circuit is keyed by its own id: three pilots admitted into one zone do not all patrol the same orbits.
// Kills: the circuit keyed by a constant.
[Fact]
public void EachPilotsPatrolCircuitIsItsOwn()
{
var (_, arena, _, failures) = Launch(new Scripted(false, stage =>
{
stage.Player(stage.Bare("Djinni"), float2(0, 0));
for (var i = 0; i < 3; i++)
stage.Place(stage.Generated("Longinus"), float2(300 + 40 * i, 0), stance: ScenarioStance.Hostile, piloted: true);
}));
Assert.True(failures.Count == 0, string.Join("; ", failures));
var circuits = arena.Agents.Select(agent => string.Join(",", ((PatrolOrbitsTask) agent.Task).Circuit.Select(key => arena.Orbits.Keys.ToList().IndexOf(key)))).ToArray();
Assert.Equal(3, circuits.Length);
Assert.True(circuits.Distinct().Count() > 1, "every pilot patrols the same orbits: " + string.Join(" | ", circuits));
}
// A fit that states its quality mints every lot it builds at it, assembly and role fills alike; the same fit without one
// draws them from the item stream, so some lot comes out otherwise. A scenario's checks rest on the first.
[Fact]