Implement deterministic simulation spine
This commit is contained in:
103
tests/SideScrollerGame.Sim.Tests/SimulationStepTests.cs
Normal file
103
tests/SideScrollerGame.Sim.Tests/SimulationStepTests.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System.Collections.Immutable;
|
||||
using SideScrollerGame.Sim.Definitions;
|
||||
using SideScrollerGame.Sim.Input;
|
||||
|
||||
namespace SideScrollerGame.Sim.Tests;
|
||||
|
||||
public sealed class SimulationStepTests
|
||||
{
|
||||
private sealed record UnsupportedAction : SimulationAction;
|
||||
|
||||
[Fact]
|
||||
public void Step_AdvancesTickSnapshotsAndMovement()
|
||||
{
|
||||
Simulation simulation = new(SimulationTestFactory.CreateGameDefinition(), SimulationTestFactory.CreateConfig(), 7);
|
||||
|
||||
var result = simulation.Step(SimulationTestFactory.CreateTick(1, new MoveAxisChanged(new(1), 2, -1), new AimAxisChanged(new(1), 30, 40), new ButtonChanged(new(1), InputButton.Jump, true), new WeaponSlotSelected(new(1), 3)));
|
||||
|
||||
Assert.Equal(1, simulation.CurrentTick);
|
||||
Assert.Equal(0, simulation.PreviousSnapshot.Tick);
|
||||
Assert.Equal(0, result.PreviousSnapshot.Tick);
|
||||
Assert.Equal(1, result.CurrentSnapshot.Tick);
|
||||
Assert.Single(result.Events);
|
||||
|
||||
var player = simulation.CurrentState.GetRequiredPlayer(new(1));
|
||||
Assert.Equal(12, player.Position.m_X.ToIntRound());
|
||||
Assert.Equal(19, player.Position.m_Y.ToIntRound());
|
||||
Assert.Equal(30, player.AimAxisX);
|
||||
Assert.Equal(40, player.AimAxisY);
|
||||
Assert.Equal(3, player.SelectedWeaponSlot);
|
||||
Assert.NotEqual(0, player.ButtonMask);
|
||||
Assert.Equal(result.StateHash, simulation.CurrentSnapshot.StateHash);
|
||||
Assert.NotEqual(0UL, simulation.CurrentSnapshot.LastRandomValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Step_RejectsUnexpectedTickNumbers()
|
||||
{
|
||||
Simulation simulation = new(SimulationTestFactory.CreateGameDefinition(), SimulationTestFactory.CreateConfig(), 7);
|
||||
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => simulation.Step(TickActionBatch.Empty(2)));
|
||||
|
||||
Assert.Contains("Expected tick 1", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Step_RejectsUnknownPlayers()
|
||||
{
|
||||
Simulation simulation = new(SimulationTestFactory.CreateGameDefinition(), SimulationTestFactory.CreateConfig(), 7);
|
||||
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => simulation.Step(SimulationTestFactory.CreateTick(1, new MoveAxisChanged(new(99), 1, 0))));
|
||||
|
||||
Assert.Contains("Unknown player id 99", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Step_RejectsUnsupportedActions()
|
||||
{
|
||||
Simulation simulation = new(SimulationTestFactory.CreateGameDefinition(), SimulationTestFactory.CreateConfig(), 7);
|
||||
|
||||
var exception = Assert.Throws<NotSupportedException>(() => simulation.Step(SimulationTestFactory.CreateTick(1, new UnsupportedAction())));
|
||||
|
||||
Assert.Contains("Unsupported action type", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_RejectsDuplicatePlayers()
|
||||
{
|
||||
GameDefinition definition = new(ImmutableArray.Create(new(new(1), new(0, 0)), new PlayerDefinition(new(1), new(2, 3))));
|
||||
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => new Simulation(definition, SimulationTestFactory.CreateConfig(), 11));
|
||||
|
||||
Assert.Contains("Duplicate player id 1", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_RejectsNullDefinition()
|
||||
{
|
||||
var exception = Assert.Throws<ArgumentNullException>(() => new Simulation(null!, SimulationTestFactory.CreateConfig(), 1));
|
||||
|
||||
Assert.Equal("gameDefinition", exception.ParamName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_RejectsNullConfig()
|
||||
{
|
||||
var exception = Assert.Throws<ArgumentNullException>(() => new Simulation(SimulationTestFactory.CreateGameDefinition(), null!, 1));
|
||||
|
||||
Assert.Equal("config", exception.ParamName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadState_RejectsNullDefinition()
|
||||
{
|
||||
var definition = SimulationTestFactory.CreateGameDefinition();
|
||||
var config = SimulationTestFactory.CreateConfig();
|
||||
Simulation simulation = new(definition, config, 2);
|
||||
var bytes = simulation.SaveState();
|
||||
|
||||
var exception = Assert.Throws<ArgumentNullException>(() => Simulation.LoadState(bytes, null!, config));
|
||||
|
||||
Assert.Equal("gameDefinition", exception.ParamName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user