using MrGameEng.AI; using Xunit; namespace MrGameEng.AI.Tests; public class SuitabilityTests { [Fact] public void Gaussian_PeaksAtOptimum() { Assert.Equal(1f, Suitability.Gaussian(18f, optimum: 18f, tolerance: 5f), 5); } [Fact] public void Gaussian_IsSymmetricAroundOptimum() { var below = Suitability.Gaussian(13f, optimum: 18f, tolerance: 5f); var above = Suitability.Gaussian(23f, optimum: 18f, tolerance: 5f); Assert.Equal(below, above, 5); } [Fact] public void Gaussian_AtOneToleranceAway_IsAboutPoint607() { Assert.Equal(MathF.Exp(-0.5f), Suitability.Gaussian(23f, 18f, 5f), 5); } [Fact] public void Gaussian_FallsOffWithDistance() { var near = Suitability.Gaussian(20f, 18f, 5f); var far = Suitability.Gaussian(30f, 18f, 5f); Assert.True(far < near && far > 0f); } [Fact] public void Gaussian_StaysWithinUnitRange() { for (var v = -50f; v <= 50f; v += 1f) { Assert.InRange(Suitability.Gaussian(v, 0f, 7f), 0f, 1f); } } [Fact] public void Gaussian_NonPositiveTolerance_IsExactMatch() { Assert.Equal(1f, Suitability.Gaussian(5f, 5f, 0f)); Assert.Equal(0f, Suitability.Gaussian(6f, 5f, 0f)); } [Fact] public void Trapezoid_IsFlatAcrossThePlateau() { Assert.Equal(1f, Suitability.Trapezoid(10f, 0f, 10f, 42f, 58f), 5); Assert.Equal(1f, Suitability.Trapezoid(25f, 0f, 10f, 42f, 58f), 5); Assert.Equal(1f, Suitability.Trapezoid(42f, 0f, 10f, 42f, 58f), 5); } [Fact] public void Trapezoid_RampsLinearlyOnEachShoulder() { Assert.Equal(0.5f, Suitability.Trapezoid(5f, 0f, 10f, 42f, 58f), 5); // halfway up the cold ramp Assert.Equal(0.5f, Suitability.Trapezoid(50f, 0f, 10f, 42f, 58f), 5); // halfway down the heat ramp } [Fact] public void Trapezoid_IsZeroAtAndBeyondTheHardLimits() { Assert.Equal(0f, Suitability.Trapezoid(0f, 0f, 10f, 42f, 58f)); Assert.Equal(0f, Suitability.Trapezoid(-5f, 0f, 10f, 42f, 58f)); Assert.Equal(0f, Suitability.Trapezoid(58f, 0f, 10f, 42f, 58f)); Assert.Equal(0f, Suitability.Trapezoid(70f, 0f, 10f, 42f, 58f)); } [Fact] public void Trapezoid_DegenerateShoulder_IsAHardStep() { // optimalLow == min: full suitability immediately above the lower limit, zero at/below it. Assert.Equal(1f, Suitability.Trapezoid(5f, 0f, 0f, 10f, 20f)); Assert.Equal(0f, Suitability.Trapezoid(0f, 0f, 0f, 10f, 20f)); } [Fact] public void Trapezoid_StaysWithinUnitRange() { for (var v = -50f; v <= 80f; v += 1f) { Assert.InRange(Suitability.Trapezoid(v, 0f, 10f, 42f, 58f), 0f, 1f); } } }