using MrGameEng.Genetics; using Xunit; namespace MrGameEng.Genetics.Tests; public class GenomeTemplateTests { private static GeneDef Numeric(string name, float min, float max) => new() { DefName = name, Kind = GeneKind.Numeric, Min = min, Max = max, }; private static GeneDef Discrete(string name, int variants = 2) => new() { DefName = name, Kind = GeneKind.Discrete, Variants = variants, }; [Fact] public void Generate_UsesPerEntryBaseAndSpread_NotGeneDefault() { var gene = Numeric("opt", min: 0f, max: 100f); // GeneDef.Default is 0 var template = new GenomeTemplate([ new GenomeTemplate.Entry(gene, Base: 50f, Spread: 0.1f), ]); var random = new Random(3); for (var i = 0; i < 200; i++) { var allele = template.Generate(random)["opt"]; Assert.InRange(allele.A, 45f, 55f); // around the template base, not 0 Assert.InRange(allele.B, 45f, 55f); } } [Fact] public void Generate_TwoSpecies_DifferInCentre() { var gene = Numeric("opt", 0f, 100f); var oak = new GenomeTemplate([new GenomeTemplate.Entry(gene, 20f, 0f)]); var grass = new GenomeTemplate([new GenomeTemplate.Entry(gene, 80f, 0f)]); Assert.Equal(20f, oak.Generate(new Random(1)).Express(gene), 3); Assert.Equal(80f, grass.Generate(new Random(1)).Express(gene), 3); } [Fact] public void Registry_CoversEntries_AndDrivesBreeding() { var template = new GenomeTemplate([ new GenomeTemplate.Entry(Numeric("a", 0f, 10f), 5f, 0.1f), new GenomeTemplate.Entry(Discrete("morph"), 0f, 0f), ]); var random = new Random(9); var a = template.Generate(random); var b = template.Generate(random); var child = Genome.Breed(a, b, template.Registry, random); Assert.True(child.Has("a")); Assert.True(child.Has("morph")); } [Fact] public void Breed_MutationChanceOverride_ForcesMutation() { var gene = Numeric("a", min: -100f, max: 100f); var registry = new Dictionary { ["a"] = gene }; var parent = new Genome { ["a"] = new Allele(10f, 10f) }; // Override chance to 1 → every inherited allele mutates away from 10. var moved = false; for (var seed = 0; seed < 30 && !moved; seed++) { var child = Genome.Breed( parent, parent, registry, new Random(seed), mutationChance: 1f ); moved = child["a"].A != 10f || child["a"].B != 10f; } Assert.True(moved, "with overridden mutationChance=1 the allele should mutate"); } [Fact] public void Breed_MutationChanceZero_KeepsAlleles() { var gene = Numeric("a", -100f, 100f); var registry = new Dictionary { ["a"] = gene }; var parent = new Genome { ["a"] = new Allele(10f, 10f) }; var child = Genome.Breed(parent, parent, registry, new Random(5), mutationChance: 0f); Assert.Equal(10f, child["a"].A); Assert.Equal(10f, child["a"].B); } }