Chessistics/chessistics-tests/Simulation/TransformerTests.cs

220 lines
8.5 KiB
C#
Raw Permalink 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 TransformerTests
{
/// <summary>
/// Build a campaign with a production, a transformer, and a demand:
/// Production(Wood) → [Transformer: Wood→Tools] → Demand(Tools)
/// Layout (5x1):
/// (0,0) Production(Wood,4)
/// (2,0) Transformer(Wood→Tools, input=2, output=1)
/// (4,0) Demand(Tools, 2)
/// </summary>
private static CampaignDef CreateTransformerCampaign()
{
return new CampaignDef
{
Name = "Transformer Test",
InitialWidth = 5,
InitialHeight = 1,
Missions =
[
new MissionDef
{
Id = 1,
Name = "Forge",
TerrainPatch = new TerrainPatch
{
NewWidth = 5,
NewHeight = 1,
Cells =
[
new PatchCell { Col = 0, Row = 0, Type = CellType.Production,
Production = new ProductionDef(new Coords(0, 0), "Scierie", CargoType.Wood, 4) },
new PatchCell { Col = 2, Row = 0, Type = CellType.Transformer,
Transformer = new TransformerDef(new Coords(2, 0), "Forge", CargoType.Wood, 2, CargoType.Tools, 1) },
new PatchCell { Col = 4, Row = 0, Type = CellType.Demand,
Demand = new DemandDef(new Coords(4, 0), "Armurerie", CargoType.Tools, 2) }
]
},
UnlockedPieces = [PieceKind.Rook],
UnlockedLevels = [new PieceUpgrade(PieceKind.Rook, 1)],
Stock = [new PieceStock(PieceKind.Rook, 3)]
}
]
};
}
[Fact]
public void Transformer_ReceivesInputCargo()
{
var campaign = CreateTransformerCampaign();
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
// Place rook between production and transformer: (1,0)↔(2,0)
// Rook oscillates between (1,0) and (2,0), picking up wood and delivering to transformer
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
var events = sim.StepN(5);
// Should see cargo transferred to the transformer position
Assert.Contains(events, e => e is CargoTransferredEvent ct
&& ct.To == new Coords(2, 0) && ct.Type == CargoType.Wood);
}
[Fact]
public void Transformer_ConvertsAfterInputThreshold()
{
var campaign = CreateTransformerCampaign();
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
// Rook delivers wood to transformer
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
var events = sim.StepN(10);
// After enough deliveries, transformation should occur
Assert.Contains(events, e => e is CargoConvertedEvent cc
&& cc.TransformerCell == new Coords(2, 0)
&& cc.InputCargo == CargoType.Wood
&& cc.OutputCargo == CargoType.Tools);
}
[Fact]
public void Transformer_OutputPickedUpByPiece()
{
var campaign = CreateTransformerCampaign();
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
// Rook 1: delivers wood to transformer
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
// Rook 2: picks up tools from transformer and delivers to demand
sim.Place(PieceKind.Rook, (3, 0), (4, 0));
var events = sim.StepN(20);
// Should see tools being transferred from transformer to rook 2
Assert.Contains(events, e => e is CargoTransferredEvent ct
&& ct.From == new Coords(2, 0) && ct.Type == CargoType.Tools);
}
[Fact]
public void Transformer_FullChain_CompleteMission()
{
var campaign = CreateTransformerCampaign();
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
// Full chain: Production → Rook1 → Transformer → Rook2 → Demand
sim.Place(PieceKind.Rook, (0, 0), (1, 0)); // delivers wood to transformer
sim.Place(PieceKind.Rook, (3, 0), (4, 0)); // picks up tools, delivers to demand
var events = sim.StepN(50);
// Mission should complete (2 tools delivered)
Assert.Contains(events, e => e is MissionCompleteEvent);
}
[Fact]
public void Transformer_DoesNotConvertWrongCargo()
{
// Transformer expects Wood but receives Stone — should not convert
var campaign = new CampaignDef
{
Name = "Wrong Cargo",
InitialWidth = 4,
InitialHeight = 1,
Missions =
[
new MissionDef
{
Id = 1, Name = "M1",
TerrainPatch = new TerrainPatch
{
NewWidth = 4, NewHeight = 1,
Cells =
[
new PatchCell { Col = 0, Row = 0, Type = CellType.Production,
Production = new ProductionDef(new Coords(0, 0), "Carriere", CargoType.Stone, 4) },
new PatchCell { Col = 2, Row = 0, Type = CellType.Transformer,
Transformer = new TransformerDef(new Coords(2, 0), "Forge", CargoType.Wood, 1, CargoType.Tools, 1) },
new PatchCell { Col = 3, Row = 0, Type = CellType.Demand,
Demand = new DemandDef(new Coords(3, 0), "D", CargoType.Tools, 1) }
]
},
UnlockedPieces = [PieceKind.Rook],
UnlockedLevels = [new PieceUpgrade(PieceKind.Rook, 1)],
Stock = [new PieceStock(PieceKind.Rook, 2)]
}
]
};
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
var events = sim.StepN(10);
// No conversion should happen (stone != wood)
Assert.DoesNotContain(events, e => e is CargoConvertedEvent);
}
[Fact]
public void Transformer_AccumulatesInput()
{
// Transformer with inputRequired=3 should accumulate over multiple deliveries
var campaign = new CampaignDef
{
Name = "Accumulate",
InitialWidth = 4,
InitialHeight = 1,
Missions =
[
new MissionDef
{
Id = 1, Name = "M1",
TerrainPatch = new TerrainPatch
{
NewWidth = 4, NewHeight = 1,
Cells =
[
new PatchCell { Col = 0, Row = 0, Type = CellType.Production,
Production = new ProductionDef(new Coords(0, 0), "Scierie", CargoType.Wood, 4) },
new PatchCell { Col = 2, Row = 0, Type = CellType.Transformer,
Transformer = new TransformerDef(new Coords(2, 0), "Forge", CargoType.Wood, 3, CargoType.Tools, 2) },
new PatchCell { Col = 3, Row = 0, Type = CellType.Demand,
Demand = new DemandDef(new Coords(3, 0), "D", CargoType.Tools, 2) }
]
},
UnlockedPieces = [PieceKind.Rook],
UnlockedLevels = [new PieceUpgrade(PieceKind.Rook, 1)],
Stock = [new PieceStock(PieceKind.Rook, 2)]
}
]
};
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
sim.Place(PieceKind.Rook, (2, 0), (3, 0));
var events = sim.StepN(30);
// After 3 wood deliveries, conversion should produce 2 tools
var conversions = events.Where(e => e is CargoConvertedEvent cc && cc.OutputAmount == 2).ToList();
Assert.NotEmpty(conversions);
// Mission should complete (2 tools delivered)
Assert.Contains(events, e => e is MissionCompleteEvent);
}
}