Bundles in-flight work on the campaign/missions system (CampaignDef, MissionDef, TerrainPatch, TransformerDef, MissionChecker, CampaignLoader, FlavorBanner, transformer rules), plan files, and matching tests. Baseline commit so the upcoming automation testing harness lands on a clean tree.
149 lines
4.4 KiB
C#
149 lines
4.4 KiB
C#
using Chessistics.Engine.Commands;
|
|
using Chessistics.Engine.Events;
|
|
using Chessistics.Engine.Model;
|
|
using Chessistics.Tests.Helpers;
|
|
using Xunit;
|
|
|
|
namespace Chessistics.Tests.Simulation;
|
|
|
|
public class GameSimTests
|
|
{
|
|
private SimHelper CreateLevel1Sim()
|
|
{
|
|
var level = new BoardBuilder(4, 4)
|
|
.WithProduction(0, 0, "Scierie", CargoType.Wood)
|
|
.WithDemand(3, 0, "Depot Royal", CargoType.Wood, 3, 30)
|
|
.WithStock(PieceKind.Rook, 3)
|
|
.Build();
|
|
return SimHelper.FromLevel(level);
|
|
}
|
|
|
|
[Fact]
|
|
public void PlacePiece_Succeeds()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
var events = sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
|
|
Assert.Single(events);
|
|
Assert.IsType<PiecePlacedEvent>(events[0]);
|
|
var placed = (PiecePlacedEvent)events[0];
|
|
Assert.Equal(PieceKind.Rook, placed.Kind);
|
|
}
|
|
|
|
[Fact]
|
|
public void PlacePiece_StockExhausted_Rejected()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
sim.Place(PieceKind.Rook, (0, 1), (1, 1));
|
|
sim.Place(PieceKind.Rook, (0, 2), (1, 2));
|
|
|
|
// 4th rook — only 3 in stock
|
|
var events = sim.Place(PieceKind.Rook, (0, 3), (1, 3));
|
|
Assert.IsType<PlacementRejectedEvent>(events[0]);
|
|
}
|
|
|
|
[Fact]
|
|
public void PlaceDuringRunning_Succeeds()
|
|
{
|
|
// In the new system, placement works in any phase
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
sim.Resume(); // Paused → Running
|
|
|
|
var events = sim.Place(PieceKind.Rook, (0, 1), (1, 1));
|
|
Assert.IsType<PiecePlacedEvent>(events[0]);
|
|
}
|
|
|
|
[Fact]
|
|
public void RemoveDuringRunning_Succeeds()
|
|
{
|
|
// In the new system, removal works in any phase
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
sim.Resume(); // Paused → Running
|
|
|
|
var events = sim.Remove(1);
|
|
Assert.IsType<PieceRemovedEvent>(events[0]);
|
|
}
|
|
|
|
[Fact]
|
|
public void SinglePiece_Oscillates()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (2, 0));
|
|
|
|
// Step 1: piece moves from (0,0) to (2,0)
|
|
var events1 = sim.Step();
|
|
Assert.Contains(events1, e => e is PieceMovedEvent m && m.From == new Coords(0, 0) && m.To == new Coords(2, 0));
|
|
|
|
// Step 2: piece moves back from (2,0) to (0,0)
|
|
var events2 = sim.Step();
|
|
Assert.Contains(events2, e => e is PieceMovedEvent m && m.From == new Coords(2, 0) && m.To == new Coords(0, 0));
|
|
|
|
// Step 3: piece moves forward again
|
|
var events3 = sim.Step();
|
|
Assert.Contains(events3, e => e is PieceMovedEvent m && m.From == new Coords(0, 0) && m.To == new Coords(2, 0));
|
|
}
|
|
|
|
[Fact]
|
|
public void ChainedPieces_TransferCargo()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
sim.Place(PieceKind.Rook, (2, 0), (3, 0));
|
|
|
|
var allEvents = sim.StepN(20);
|
|
|
|
Assert.Contains(allEvents, e => e is CargoProducedEvent);
|
|
Assert.Contains(allEvents, e => e is CargoTransferredEvent);
|
|
}
|
|
|
|
[Fact]
|
|
public void Production_GeneratesEveryTurn()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
|
|
|
|
var allEvents = sim.StepN(6);
|
|
|
|
var prodEvents = allEvents.OfType<CargoProducedEvent>().ToList();
|
|
Assert.Equal(6, prodEvents.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void MissionComplete_WhenAllDemandsMet()
|
|
{
|
|
var level = new BoardBuilder(3, 1)
|
|
.WithProduction(0, 0, "P", CargoType.Wood)
|
|
.WithDemand(2, 0, "D", CargoType.Wood, 1, 30)
|
|
.WithStock(PieceKind.Rook, 2)
|
|
.Build();
|
|
var sim = SimHelper.FromLevel(level);
|
|
|
|
sim.Place(PieceKind.Rook, (1, 0), (2, 0));
|
|
|
|
var allEvents = sim.StepN(10);
|
|
|
|
Assert.Contains(allEvents, e => e is MissionCompleteEvent);
|
|
}
|
|
|
|
[Fact]
|
|
public void InitialPhase_IsPaused()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
var snap = sim.Snapshot;
|
|
Assert.Equal(SimPhase.Paused, snap.Phase);
|
|
}
|
|
|
|
[Fact]
|
|
public void StepFromPaused_Works()
|
|
{
|
|
var sim = CreateLevel1Sim();
|
|
sim.Place(PieceKind.Rook, (1, 0), (2, 0));
|
|
|
|
// Step directly from Paused
|
|
var events = sim.Step();
|
|
Assert.Contains(events, e => e is TurnStartedEvent);
|
|
}
|
|
}
|