Chessistics/chessistics-tests/Simulation/GameSimTests.cs

150 lines
4.4 KiB
C#
Raw Normal View History

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);
}
}