using Fighter3D.Core; using XWorld.Framework; namespace XWorld.Server.Host.Tests { public class Fighter3DLogicTests { private static FighterState NewState() { return new FighterLogic().CreateInitial( new RoomConfig { GameId = "fighter3d", Version = 1, Seed = 1, PlayerCount = 2 }, new DeterministicRandom(1)); } [Fact] public void InitialState_StartsTwoFightersMirrored() { var state = NewState(); Assert.Equal(FighterPhase.Running, state.Phase); Assert.Equal(1000, state.Fighters[0].Hp); Assert.Equal(1000, state.Fighters[1].Hp); Assert.True(state.Fighters[0].X < state.Fighters[1].X); Assert.Equal(1, state.Fighters[0].Facing); Assert.Equal(-1, state.Fighters[1].Facing); } [Fact] public void Movement_ClampsToStageBounds() { var logic = new FighterLogic(); var state = NewState(); state = logic.Step(state, FighterInput.Controls(0, -1, FighterButtons.None), null).State; for (int i = 0; i < 600; i++) state = logic.Step(state, FighterInput.Tick(1f / FighterLogic.TickRate), null).State; Assert.Equal(-FighterLogic.StageHalfWidth, state.Fighters[0].X, 3); } [Fact] public void LightAttack_HitsOpponentAndAppliesStun() { var logic = new FighterLogic(); var state = NewState(); state.Fighters[0].X = -0.4f; state.Fighters[1].X = 0.4f; state = logic.Step(state, FighterInput.Controls(0, 0, FighterButtons.Light), null).State; for (int i = 0; i < 10; i++) state = logic.Step(state, FighterInput.Tick(1f / FighterLogic.TickRate), null).State; Assert.True(state.Fighters[1].Hp < 1000); Assert.Equal(FighterAction.HitStun, state.Fighters[1].Action); } [Fact] public void HoldingAway_BlocksIncomingAttack() { var logic = new FighterLogic(); var state = NewState(); state.Fighters[0].X = -0.4f; state.Fighters[1].X = 0.4f; state = logic.Step(state, FighterInput.Controls(1, 1, FighterButtons.None), null).State; state = logic.Step(state, FighterInput.Controls(0, 0, FighterButtons.Light), null).State; for (int i = 0; i < 10; i++) state = logic.Step(state, FighterInput.Tick(1f / FighterLogic.TickRate), null).State; Assert.Equal(1000, state.Fighters[1].Hp); Assert.Equal(FighterAction.BlockStun, state.Fighters[1].Action); } [Fact] public void Timeout_WinnerIsHigherHealthSeat() { var logic = new FighterLogic(); var state = NewState(); state.Fighters[1].Hp = 900; state = logic.Step(state, FighterInput.Tick(FighterLogic.RoundSeconds), null).State; Assert.Equal(FighterPhase.Finished, state.Phase); Assert.Equal(0, state.WinnerSeat); } [Fact] public void EncodeDecode_RoundTripsSnapshot() { var logic = new FighterLogic(); var state = NewState(); state.Tick = 123; state.ElapsedSeconds = 2.5f; state.Fighters[0].Hp = 777; state.Fighters[1].Action = FighterAction.BlockStun; state.Fighters[1].ActionFrame = 6; state.WinnerSeat = 1; var back = logic.Decode(logic.Encode(state)); Assert.Equal(123, back.Tick); Assert.Equal(2.5f, back.ElapsedSeconds, 3); Assert.Equal(777, back.Fighters[0].Hp); Assert.Equal(FighterAction.BlockStun, back.Fighters[1].Action); Assert.Equal(6, back.Fighters[1].ActionFrame); Assert.Equal(1, back.WinnerSeat); } } }