using Chessistics.Engine.Commands; using Chessistics.Engine.Events; using Chessistics.Engine.Model; using Chessistics.Tests.Helpers; using Xunit; namespace Chessistics.Tests.Simulation; public class RecurringDemandTests { private SimHelper BuildRecurringLevel() { var level = new LevelDef { Width = 3, Height = 1, Productions = new List { new(new Coords(0, 0), "Scierie", CargoType.Wood, 1) }, Demands = new List { new(new Coords(2, 0), "Ville", CargoType.Wood, Amount: 1, Deadline: 0, ConsumptionPerTurn: 1, SustainTurns: 3) }, Walls = new List(), Stock = new List { new(PieceKind.Rook, 1) } }; return SimHelper.FromLevel(level); } [Fact] public void RecurringDemand_WithoutSupply_EntersShortage() { var sim = BuildRecurringLevel(); // No piece placed — demand never fed, but doesn't consume anything // it doesn't have. The first turn should already flag shortage. var events = sim.Step(); Assert.Contains(events, e => e is DemandShortageStartedEvent); // SustainedTurns should stay 0 while in shortage var demand = sim.Snapshot.Demands[0]; Assert.False(demand.IsSatisfied); } [Fact] public void RecurringDemand_BufferFeedsConsumption() { // Direct unit-style test: start a recurring demand with a filled // buffer and confirm consumption + sustain counter tick correctly. var demand = new DemandState( new DemandDef(new Coords(0, 0), "V", CargoType.Wood, Amount: 0, Deadline: 0, ConsumptionPerTurn: 1, SustainTurns: 3)) { Buffer = 5 }; // Simulate 3 turns of consumption with no deliveries: should not // shortage (buffer covers), SustainedTurns accrues. for (int i = 0; i < 3; i++) { var consumed = System.Math.Min(demand.Buffer, demand.Definition.ConsumptionPerTurn); demand.Buffer -= consumed; if (demand.Buffer <= 0) { demand.InShortage = true; demand.SustainedTurns = 0; } else { demand.InShortage = false; demand.SustainedTurns++; } } Assert.False(demand.InShortage); Assert.Equal(3, demand.SustainedTurns); Assert.True(demand.IsSatisfied); } [Fact] public void ClassicDemand_NotRecurring_BehavesAsBefore() { var level = new BoardBuilder(3, 1) .WithProduction(0, 0, "S", CargoType.Wood) .WithDemand(2, 0, "D", CargoType.Wood, 2, 20) .WithStock(PieceKind.Rook, 1) .Build(); var sim = SimHelper.FromLevel(level); sim.Place(PieceKind.Rook, (1, 0), (2, 0)); var events = sim.StepN(20); Assert.DoesNotContain(events, e => e is DemandShortageStartedEvent); Assert.Contains(events, e => e is MissionCompleteEvent); } }