/// <summary> /// Creates a mutated version of a species /// </summary> public MicrobeSpecies CreateMutatedSpecies(MicrobeSpecies parent, MicrobeSpecies mutated) { if (parent.Organelles.Count < 1) { throw new ArgumentException("Can't create a mutated version of an empty species"); } var simulation = SimulationParameters.Instance; var nameGenerator = simulation.NameGenerator; mutated.IsBacteria = parent.IsBacteria; // Mutate the epithet if (random.Next(0, 101) < Constants.MUTATION_WORD_EDIT) { mutated.Epithet = MutateWord(parent.Epithet); } else { mutated.Epithet = nameGenerator.GenerateNameSection(); } mutated.Genus = parent.Genus; MutateBehaviour(parent, mutated); if (random.Next(0, 101) <= Constants.MUTATION_CHANGE_GENUS) { // We can do more fun stuff here later if (random.Next(0, 101) < Constants.MUTATION_WORD_EDIT) { mutated.Genus = MutateWord(parent.Genus); } else { mutated.Genus = nameGenerator.GenerateNameSection(); } } MutateMicrobeOrganelles(parent.Organelles, mutated.Organelles, mutated.IsBacteria); // There is a small chance of evolving into a eukaryote var nucleus = simulation.GetOrganelleType("nucleus"); if (mutated.Organelles.Any(o => o.Definition == nucleus)) { mutated.IsBacteria = false; } var colour = mutated.IsBacteria ? RandomProkaryoteColour() : RandomEukaryoteColour(); if (random.Next(0, 101) <= 20) { // Could perhaps use a weighted entry model here... the // earlier one is listed, the more likely currently (I // think). That may be an issue. if (random.Next(0, 101) < 50) { mutated.MembraneType = simulation.GetMembrane("single"); } else if (random.Next(0, 101) < 50) { mutated.MembraneType = simulation.GetMembrane("double"); colour.a = RandomOpacityChitin(); } else if (random.Next(0, 101) < 50) { mutated.MembraneType = simulation.GetMembrane("cellulose"); } else if (random.Next(0, 101) < 50) { mutated.MembraneType = simulation.GetMembrane("chitin"); colour.a = RandomOpacityChitin(); } else if (random.Next(0, 101) < 50) { mutated.MembraneType = simulation.GetMembrane("calcium_carbonate"); colour.a = RandomOpacityChitin(); } else { mutated.MembraneType = simulation.GetMembrane("silica"); colour.a = RandomOpacityChitin(); } } else { mutated.MembraneType = parent.MembraneType; } mutated.Colour = colour; mutated.MembraneRigidity = Math.Max(Math.Min(parent.MembraneRigidity + random.Next(-25, 26) / 100.0f, 1), -1); mutated.UpdateInitialCompounds(); return(mutated); }
/// <summary> /// Creates a mutated version of a species /// </summary> public MicrobeSpecies CreateMutatedSpecies(MicrobeSpecies parent, MicrobeSpecies mutated) { if (parent.Organelles.Count < 1) { throw new ArgumentException("Can't create a mutated version of an empty species"); } var simulation = SimulationParameters.Instance; var nameGenerator = simulation.NameGenerator; mutated.IsBacteria = parent.IsBacteria; // Mutate the epithet if (random.Next(0, 101) < Constants.MUTATION_WORD_EDIT) { mutated.Epithet = MutateWord(parent.Epithet); } else { mutated.Epithet = nameGenerator.GenerateNameSection(); } MutateBehaviour(parent, mutated); MutateMicrobeOrganelles(parent.Organelles, mutated.Organelles, mutated.IsBacteria); // Update the genus if the new species is different enough if (NewGenus(mutated, parent)) { // We can do more fun stuff here later if (random.Next(0, 101) < Constants.MUTATION_WORD_EDIT) { mutated.Genus = MutateWord(parent.Genus); } else { mutated.Genus = nameGenerator.GenerateNameSection(); } } else { mutated.Genus = parent.Genus; } // If the new species is a eukaryote, mark this as such var nucleus = simulation.GetOrganelleType("nucleus"); if (mutated.Organelles.Any(o => o.Definition == nucleus)) { mutated.IsBacteria = false; } // Update colour and membrane var colour = mutated.IsBacteria ? RandomProkaryoteColour() : RandomEukaryoteColour(); if (random.Next(0, 101) <= 20) { mutated.MembraneType = RandomMembraneType(simulation); if (mutated.MembraneType != simulation.GetMembrane("single")) { colour.a = RandomOpacityChitin(); } } else { mutated.MembraneType = parent.MembraneType; } mutated.Colour = colour; mutated.MembraneRigidity = Math.Max(Math.Min(parent.MembraneRigidity + random.Next(-25, 26) / 100.0f, 1), -1); mutated.RepositionToOrigin(); mutated.UpdateInitialCompounds(); return(mutated); }