private void MutateBehaviour(MicrobeSpecies parent, MicrobeSpecies mutated) { // Variables used in AI to determine general behavior mutate these float aggression = parent.Aggression + random.Next( Constants.MIN_SPECIES_PERSONALITY_MUTATION, Constants.MAX_SPECIES_PERSONALITY_MUTATION); float fear = parent.Fear + random.Next( Constants.MIN_SPECIES_PERSONALITY_MUTATION, Constants.MAX_SPECIES_PERSONALITY_MUTATION); float activity = parent.Activity + random.Next( Constants.MIN_SPECIES_PERSONALITY_MUTATION, Constants.MAX_SPECIES_PERSONALITY_MUTATION); float focus = parent.Focus + random.Next( Constants.MIN_SPECIES_PERSONALITY_MUTATION, Constants.MAX_SPECIES_PERSONALITY_MUTATION); float opportunism = parent.Opportunism + random.Next( Constants.MIN_SPECIES_PERSONALITY_MUTATION, Constants.MAX_SPECIES_PERSONALITY_MUTATION); // Make sure not over or under our scales // This used to be a method as well mutated.Aggression = aggression.Clamp(0.0f, Constants.MAX_SPECIES_AGRESSION); mutated.Fear = fear.Clamp(0.0f, Constants.MAX_SPECIES_FEAR); mutated.Activity = activity.Clamp(0.0f, Constants.MAX_SPECIES_ACTIVITY); mutated.Focus = focus.Clamp(0.0f, Constants.MAX_SPECIES_FOCUS); mutated.Opportunism = opportunism.Clamp(0.0f, Constants.MAX_SPECIES_OPPORTUNISM); }
/// <summary> /// Creates an empty species object /// </summary> public MicrobeSpecies NewMicrobeSpecies() { var species = new MicrobeSpecies(++speciesIdCounter); worldSpecies[species.ID] = species; return(species); }
private static float GetCompoundUseScore(MicrobeSpecies species, Compound compound) { var compoundUseScore = 0.0f; foreach (var organelle in species.Organelles) { foreach (var process in organelle.Definition.RunnableProcesses) { if (process.Process.Inputs.ContainsKey(compound)) { if (process.Process.Outputs.ContainsKey(Glucose)) { compoundUseScore += process.Process.Outputs[Glucose] / process.Process.Inputs[compound] / Constants.AUTO_EVO_GLUCOSE_USE_SCORE_DIVISOR; } if (process.Process.Outputs.ContainsKey(ATP)) { compoundUseScore += process.Process.Outputs[ATP] / process.Process.Inputs[compound] / Constants.AUTO_EVO_ATP_USE_SCORE_DIVISOR; } } } } return(compoundUseScore); }
protected float EnergyGenerationScore(MicrobeSpecies species, Compound compound) { var energyCreationScore = 0.0f; foreach (var organelle in species.Organelles) { foreach (var process in organelle.Definition.RunnableProcesses) { if (process.Process.Inputs.ContainsKey(compound)) { if (process.Process.Outputs.ContainsKey(glucose)) { energyCreationScore += process.Process.Outputs[glucose] / process.Process.Inputs[compound] * Constants.AUTO_EVO_GLUCOSE_USE_SCORE_MULTIPLIER; } if (process.Process.Outputs.ContainsKey(atp)) { energyCreationScore += process.Process.Outputs[atp] / process.Process.Inputs[compound] * Constants.AUTO_EVO_ATP_USE_SCORE_MULTIPLIER; } } } } return(energyCreationScore); }
/// <summary> /// Used to determine if a newly mutated species needs to be in a different genus. /// </summary> /// <param name="species1">The first species. Function is not order-dependent.</param> /// <param name="species2">The second species. Function is not order-dependent.</param> /// <returns>True if the two species should be a new genus, false otherwise.</returns> private bool NewGenus(MicrobeSpecies species1, MicrobeSpecies species2) { var species1UniqueOrganelles = species1.Organelles.Select(o => o.Definition).ToHashSet(); var species2UniqueOrganelles = species2.Organelles.Select(o => o.Definition).ToHashSet(); return(species1UniqueOrganelles.Union(species2UniqueOrganelles).Count() - species1UniqueOrganelles.Intersect(species2UniqueOrganelles).Count() >= Constants.DIFFERENCES_FOR_GENUS_SPLIT); }
public HeterotrophicFoodSource(Patch patch, MicrobeSpecies prey) { this.prey = prey; this.patch = patch; preyHexSize = prey.BaseHexSize; preySpeed = prey.BaseSpeed; patch.SpeciesInPatch.TryGetValue(prey, out long population); totalEnergy = population * prey.Organelles.Count * Constants.AUTO_EVO_PREDATION_ENERGY_MULTIPLIER; }
public void AddTrackedEnergyConsumptionForSpecies(MicrobeSpecies species, Patch patch, long unadjustedPopulation, float totalEnergy, float individualCost) { MakeSureResultExistsForSpecies(species); var dataReceiver = results[species].GetEnergyResults(patch); dataReceiver.UnadjustedPopulation = unadjustedPopulation; dataReceiver.TotalEnergyGathered = totalEnergy; dataReceiver.IndividualCost = individualCost; }
/// <summary> /// Set up full SpawnItems and MicrobeItems bags in the spawnSystem based on the counts dictionaries. /// </summary> private void SetFullSpawnBags() { spawnBagSize = 0; foreach (Compound compound in compoundCloudCounts.Keys) { spawnBagSize += compoundCloudCounts[compound]; for (int i = 0; i < compoundCloudCounts[compound]; i++) { spawnSystem.AddSpawnItem(new CloudItem(compound, compoundAmounts[compound], CloudSpawner)); } } foreach (ChunkConfiguration chunk in chunkCounts.Keys) { spawnBagSize += chunkCounts[chunk]; foreach (var mesh in chunk.Meshes) { if (mesh.LoadedScene == null) { throw new ArgumentException("configured chunk spawner has a mesh that has no scene loaded"); } } for (int i = 0; i < chunkCounts[chunk]; i++) { spawnSystem.AddSpawnItem(new ChunkItem(chunk, ChunkSpawner)); } } foreach (Species key in speciesCounts.Keys) { if (!(key is MicrobeSpecies)) { continue; } MicrobeSpecies species = (MicrobeSpecies)key; spawnBagSize += speciesCounts[key]; for (int i = 0; i < speciesCounts[key]; i++) { MicrobeItem microbeItem = new MicrobeItem(species, MicrobeSpawner); microbeItem.IsWanderer = false; spawnSystem.AddSpawnItem(microbeItem); MicrobeItem wanderMicrobeItem = new MicrobeItem(species, MicrobeSpawner); wanderMicrobeItem.IsWanderer = true; spawnSystem.AddMicrobeItem(wanderMicrobeItem); } } spawnSystem.SetMicrobeBagSize(); }
public static void SetInitialSpeciesProperties(MicrobeSpecies species) { species.IsBacteria = true; species.SetInitialCompoundsForDefault(); species.Genus = "Primum"; species.Epithet = "Thrivium"; species.MembraneType = SimulationParameters.Instance.GetMembrane("single"); species.Organelles.Add(new OrganelleTemplate( SimulationParameters.Instance.GetOrganelleType("cytoplasm"), new Hex(0, 0), 0)); }
public IEnumerable <ISpawned> Spawn(Node worldNode, Vector3 location, MicrobeSpecies species, bool isWanderer) { // The true here is that this is AI controlled ISpawned first = Spawn(species, location, worldNode, microbeScene, true, cloudSystem, CurrentGame); yield return(first); if (species.IsBacteria && !isWanderer) { foreach (Microbe microbe in SpawnBacteriaColony(species, location, worldNode, microbeScene, cloudSystem, CurrentGame, random)) { yield return(microbe); } } }
public override object Clone() { var result = new MicrobeSpecies(ID); ClonePropertiesTo(result); result.IsBacteria = IsBacteria; result.MembraneType = MembraneType; result.MembraneRigidity = MembraneRigidity; foreach (var organelle in Organelles) { result.Organelles.Add((OrganelleTemplate)organelle.Clone()); } return(result); }
/// <summary> /// Creates a fully random species starting with one cytoplasm /// </summary> public MicrobeSpecies CreateRandomSpecies(MicrobeSpecies mutated, int steps = 5) { // Temporarily create species with just cytoplasm to start mutating from var temp = new MicrobeSpecies(int.MaxValue); GameWorld.SetInitialSpeciesProperties(temp); // TODO: in the old code GenerateNameSection was used to // override the default species name here for (int step = 0; step < steps; ++step) { CreateMutatedSpecies(temp, mutated); temp = (MicrobeSpecies)mutated.Clone(); } return(mutated); }
private void SetupEditedSpecies(MicrobeSpecies species) { if (species == null) { throw new NullReferenceException("didn't find edited species"); } editedSpecies = species; // We need to set the membrane type here so the ATP balance // bar can take it into account (the bar is updated when // organelles are added) Membrane = species.MembraneType; Rigidity = species.MembraneRigidity; // Get the species organelles to be edited. This also updates the placeholder hexes foreach (var organelle in species.Organelles.Organelles) { editedMicrobeOrganelles.Add((OrganelleTemplate)organelle.Clone()); } GD.Print("Starting microbe editor with: ", editedMicrobeOrganelles.Organelles.Count, " organelles in the microbe, genes: ", species.StringCode); // Update GUI buttons now that we have correct organelles gui.UpdateGuiButtonStatus(HasNucleus); // Create a mutated version of the current species code to compete against the player CreateMutatedSpeciesCopy(species); // Reset to cytoplasm if nothing is selected if (ActiveActionName == null) { gui.OnOrganelleToPlaceSelected("cytoplasm"); } NewName = species.FormattedName; gui.SetSpeciesInfo(NewName, Membrane, species.Colour, Rigidity); species.Generation += 1; gui.UpdateGeneration(species.Generation); }
/// <summary> /// Creates a fully random species starting with one cytoplasm /// </summary> public MicrobeSpecies CreateRandomSpecies(MicrobeSpecies mutated, int steps = 5) { // Temporarily create species with just cytoplasm to start mutating from var temp = new MicrobeSpecies(int.MaxValue); GameWorld.SetInitialSpeciesProperties(temp); // Override the default species starting name to have more variability in the names var nameGenerator = SimulationParameters.Instance.NameGenerator; temp.Epithet = nameGenerator.GenerateNameSection(); temp.Genus = nameGenerator.GenerateNameSection(); for (int step = 0; step < steps; ++step) { CreateMutatedSpecies(temp, mutated); temp = (MicrobeSpecies)mutated.Clone(); } return(mutated); }
public void AddTrackedEnergyForSpecies(MicrobeSpecies species, Patch patch, FoodSource niche, float speciesFitness, float speciesEnergy, float totalFitness) { if (niche == null) { throw new ArgumentException("niche is missing", nameof(niche)); } MakeSureResultExistsForSpecies(species); var dataReceiver = results[species].GetEnergyResults(patch); var nicheDescription = niche.GetDescription(); dataReceiver.PerNicheEnergy[nicheDescription] = new SpeciesPatchEnergyResults.NicheInfo { CurrentSpeciesFitness = speciesFitness, CurrentSpeciesEnergy = speciesEnergy, TotalFitness = totalFitness, TotalAvailableEnergy = niche.TotalEnergyAvailable(), }; }
private static float GetPredationScore(MicrobeSpecies species) { var predationScore = 0.0f; foreach (var organelle in species.Organelles) { if (organelle.Definition.HasComponentFactory <PilusComponentFactory>()) { predationScore += Constants.AUTO_EVO_PILUS_PREDATION_SCORE; continue; } foreach (var process in organelle.Definition.RunnableProcesses) { if (process.Process.Outputs.ContainsKey(Oxytoxy)) { predationScore += Constants.AUTO_EVO_TOXIN_PREDATION_SCORE; } } } return(predationScore); }
public MicrobeItem(MicrobeSpecies species, MicrobeSpawner microbeSpawner) { this.species = species; MicrobeSpawner = microbeSpawner; }
/// <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); }
/// <summary> /// Creates a mutated version of a species /// </summary> public MicrobeSpecies CreateMutatedSpecies(MicrobeSpecies parent, MicrobeSpecies mutated) { 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 ? RandomProkayroteColour() : RandomColour(); 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.MembraneRigidity = Math.Max(Math.Min(parent.MembraneRigidity + random.Next(-25, 26) / 100.0f, 1), -1); // If you have iron (f is the symbol for rusticyanin) var rusticyanin = simulation.GetOrganelleType("rusticyanin"); var chemo = simulation.GetOrganelleType("chemoplast"); var chemoProtein = simulation.GetOrganelleType("chemoSynthesizingProteins"); if (mutated.Organelles.Any(o => o.Definition == rusticyanin)) { mutated.SetInitialCompoundsForIron(); } else if (mutated.Organelles.Any(o => o.Definition == chemo || o.Definition == chemoProtein)) { mutated.SetInitialCompoundsForChemo(); } else { mutated.SetInitialCompoundsForDefault(); } return(mutated); }