public List <Genome> Reproduce(int expectedChildren, InnovationPool seenInnovations, List <Species> interBredSpecies, Random rando) { List <Genome> children = new List <Genome>(); bool champDone = false; while (expectedChildren > 0) { if (!champDone && expectedChildren >= Const.ChampSurvivalThresh) { children.Add(Fitness.Champion); champDone = true; } else if (rando.NextDouble() < Const.MutateOnlyProbability || expectedChildren == 1) { Genome child = new Genome(Genomes[rando.Next(Size())]); Mutation.Mutate(child, seenInnovations, rando); children.Add(child); } else { Genome mother = Genomes[rando.Next(Size())]; Genome father = null; if (rando.NextDouble() < Const.InterSpeciesBreedingProbability) { Species spec = SelectOtherSpecies(interBredSpecies, rando); father = spec.Fitness.Champion; } else { father = Genomes[rando.Next(Size())]; } Genome child = Mating.Mate(mother, father, rando); //TODO: Add mother/father node checking criteria as well? if (rando.NextDouble() >= Const.MateOnlyProbability || GenomeCompatibility.Compatibility(mother, father) == 0.0) { Mutation.Mutate(child, seenInnovations, rando); } children.Add(child); } expectedChildren--; } return(children); }
/// <summary> /// Sorts next generation into their respective species. /// </summary> /// <param name="nextGen">The next generation.</param> private void SpeciateNewGeneration(List <Genome> nextGen) { foreach (var child in nextGen) { bool speciesFound = false; foreach (var spec in Species) { if (GenomeCompatibility.Compatibility(spec.Template, child) <= GenomeCompatibility.SpeciesCompatibilityThreshold) { spec.Genomes.Add(child); speciesFound = true; break; } } if (!speciesFound) { //TODO: Find a better way of doing age. Species spec = new Species(child); spec.Age = -1; Species.Add(spec); } } }