Chessistics/chessistics-tests/Simulation/FullLevelTests.cs

136 lines
5.2 KiB
C#
Raw Normal View History

using Chessistics.Engine.Events;
using Chessistics.Engine.Model;
using Chessistics.Tests.Helpers;
using Xunit;
namespace Chessistics.Tests.Simulation;
public class FullLevelTests
{
[Fact]
public void Level1_PremierConvoi_Victory()
{
// GDD Level 1: 4x4, Scierie(0,0) → Depot(3,0), 3 Rooks
// Solution: single rook relay at (1,0)↔(2,0)
var level = new BoardBuilder(4, 4)
.WithProduction(0, 0, "Scierie", CargoType.Wood, 2)
.WithDemand(3, 0, "Depot Royal", CargoType.Wood, 3, 30)
.WithStock(PieceKind.Rook, 3)
.Build();
var sim = SimHelper.FromLevel(level);
sim.Place(PieceKind.Rook, (1, 0), (2, 0));
sim.Start();
var allEvents = sim.StepN(30);
Assert.Contains(allEvents, e => e is VictoryEvent);
}
[Fact]
public void Level2_DeuxClients_Victory()
{
// GDD Level 2: 6x6, Scierie(0,0), Depot Royal(5,0), Caserne(5,4)
// Stock: 6 Rooks + 1 Bishop (fixed from GDD's 4R+1B — insufficient)
//
// Solution requires two routes from single source:
// Route 1 → (5,0): A(1,0↔2,0), B(2,0↔4,0)
// Route 2 → (5,4): C(0,1↔0,2), D(0,2↔2,2), E(2,2↔3,2),
// Bishop(3,2↔4,3), G(4,3↔5,3)
// Total needed: 6 Rooks + 1 Bishop
var level = new BoardBuilder(6, 6)
.WithProduction(0, 0, "Scierie", CargoType.Wood, 2)
.WithDemand(5, 0, "Depot Royal", CargoType.Wood, 2, 50)
.WithDemand(5, 4, "Caserne", CargoType.Wood, 2, 50)
.WithStock(PieceKind.Rook, 6)
.WithStock(PieceKind.Bishop, 1)
.Build();
var sim = SimHelper.FromLevel(level);
// Route 1: bottom row → demand (5,0)
sim.Place(PieceKind.Rook, (1, 0), (2, 0));
sim.Place(PieceKind.Rook, (2, 0), (4, 0));
// Route 2: up then right → demand (5,4)
sim.Place(PieceKind.Rook, (0, 1), (0, 2));
sim.Place(PieceKind.Rook, (0, 2), (2, 2));
// 5th rook — stock exhausted at 4!
var events5 = sim.Place(PieceKind.Rook, (2, 2), (3, 2));
Assert.DoesNotContain(events5, e => e is PlacementRejectedEvent);
sim.Place(PieceKind.Bishop, (3, 2), (4, 3));
// 6th rook needed but only 4 in stock
var events6 = sim.Place(PieceKind.Rook, (4, 3), (5, 3));
Assert.DoesNotContain(events6, e => e is PlacementRejectedEvent);
sim.Start();
var allEvents = sim.StepN(60);
Assert.Contains(allEvents, e => e is VictoryEvent);
}
[Fact]
public void Level3_LeCol_Victory()
{
// GDD Level 3: 6x6, L-shaped wall, 2 cargo types, knights jump obstacle
// Stock: 8 Rooks + 2 Knights (fixed from GDD's 4R+1B+2K)
//
// CargoFilter (Phase 2) prevents cross-route contamination:
// pieces auto-inherit their production's cargo type via relay chain.
//
// Route Wood (0,0→5,5): R1(0,1↔1,1), K1(1,1↔3,2),
// R2(3,2↔4,2), R3(4,2↔5,2), R4(5,2↔5,3), R5(5,3↔5,4)
// Route Stone (5,0→0,5): S1(4,0↔3,0), S2(3,0↔2,0),
// K2(2,0↔1,2), S3(1,2↔1,3), S4(1,3↔1,4), S5(1,4↔0,4)
// Total: 10 Rooks + 2 Knights
var level = new BoardBuilder(6, 6)
.WithProduction(0, 0, "Scierie", CargoType.Wood, 2)
.WithProduction(5, 0, "Carriere", CargoType.Stone, 2)
.WithDemand(5, 5, "Depot Royal", CargoType.Wood, 2, 60)
.WithDemand(0, 5, "Forge", CargoType.Stone, 2, 60)
.WithWall(2, 2).WithWall(2, 3).WithWall(2, 4).WithWall(3, 4).WithWall(4, 4)
.WithStock(PieceKind.Rook, 10)
.WithStock(PieceKind.Knight, 2)
.Build();
var sim = SimHelper.FromLevel(level);
// Route Wood: prod(0,0) → demand(5,5)
sim.Place(PieceKind.Rook, (0, 1), (1, 1));
sim.Place(PieceKind.Knight, (1, 1), (3, 2));
sim.Place(PieceKind.Rook, (3, 2), (4, 2));
sim.Place(PieceKind.Rook, (4, 2), (5, 2));
sim.Place(PieceKind.Rook, (5, 2), (5, 3));
sim.Place(PieceKind.Rook, (5, 3), (5, 4));
// Route Stone: prod(5,0) → demand(0,5)
sim.Place(PieceKind.Rook, (4, 0), (3, 0));
sim.Place(PieceKind.Rook, (3, 0), (2, 0));
sim.Place(PieceKind.Knight, (2, 0), (1, 2));
sim.Place(PieceKind.Rook, (1, 2), (1, 3));
sim.Place(PieceKind.Rook, (1, 3), (1, 4));
sim.Place(PieceKind.Rook, (1, 4), (0, 4));
sim.Start();
var allEvents = sim.StepN(80);
Assert.Contains(allEvents, e => e is VictoryEvent);
}
[Fact]
public void Level1_InsufficientPieces_NoVictory()
{
var level = new BoardBuilder(4, 4)
.WithProduction(0, 0, "Scierie", CargoType.Wood, 2)
.WithDemand(3, 3, "Depot Royal", CargoType.Wood, 3, 5)
.WithStock(PieceKind.Rook, 1)
.Build();
var sim = SimHelper.FromLevel(level);
sim.Place(PieceKind.Rook, (1, 1), (2, 1));
sim.Start();
var allEvents = sim.StepN(8);
Assert.DoesNotContain(allEvents, e => e is VictoryEvent);
Assert.Contains(allEvents, e => e is DeadlineExpiredEvent);
}
}