public IncreaseBiodiversity(AutoEvoConfiguration configuration, PatchMap map, Patch patch, Random random) { this.map = map; this.patch = patch; this.configuration = configuration; this.random = new Random(random.Next()); }
public SimulationConfiguration(AutoEvoConfiguration autoEvoConfiguration, PatchMap initialConditions, int steps = 1) { AutoEvoConfiguration = autoEvoConfiguration; OriginalMap = initialConditions; StepsLeft = Math.Max(1, steps); }
public FindBestMigration(AutoEvoConfiguration configuration, PatchMap map, Species species, Random random, int migrationsToTry, bool allowNoMigration) : base(migrationsToTry, allowNoMigration) { this.configuration = configuration; this.map = map; this.species = species; this.random = new Random(random.Next()); }
/// <summary> /// Loads the simulation configuration parameters from JSON files /// </summary> /// <remarks> /// This is now loaded in _Ready as otherwise the <see cref="ModLoader"/>'s _Ready would run after simulation /// parameters are loaded causing some data that might want to be overridden by mods to be loaded too early. /// </remarks> public override void _Ready() { base._Ready(); // Compounds are referenced by the other json files so it is loaded first and instance is assigned here instance = this; // Loading the compounds needs a custom JSON deserializer that can load the Compound objects, but the loader // can't always be active because that breaks saving { var compoundDeserializer = new JsonConverter[] { new CompoundLoader(null) }; compounds = LoadRegistry <Compound>( "res://simulation_parameters/microbe_stage/compounds.json", compoundDeserializer); } membranes = LoadRegistry <MembraneType>( "res://simulation_parameters/microbe_stage/membranes.json"); backgrounds = LoadRegistry <Background>( "res://simulation_parameters/microbe_stage/backgrounds.json"); biomes = LoadRegistry <Biome>( "res://simulation_parameters/microbe_stage/biomes.json"); bioProcesses = LoadRegistry <BioProcess>( "res://simulation_parameters/microbe_stage/bio_processes.json"); organelles = LoadRegistry <OrganelleDefinition>( "res://simulation_parameters/microbe_stage/organelles.json"); NameGenerator = LoadDirectObject <NameGenerator>( "res://simulation_parameters/microbe_stage/species_names.json"); musicCategories = LoadRegistry <MusicCategory>("res://simulation_parameters/common/music_tracks.json"); helpTexts = LoadRegistry <HelpTexts>("res://simulation_parameters/common/help_texts.json"); inputGroups = LoadListRegistry <NamedInputGroup>("res://simulation_parameters/common/input_options.json"); autoEvoConfiguration = LoadDirectObject <AutoEvoConfiguration>("res://simulation_parameters/common/auto-evo_parameters.json"); gallery = LoadRegistry <Gallery>("res://simulation_parameters/common/gallery.json"); translationsInfo = LoadDirectObject <TranslationsInfo>("res://simulation_parameters/common/translations_info.json"); gameCredits = LoadDirectObject <GameCredits>("res://simulation_parameters/common/credits.json"); GD.Print("SimulationParameters loading ended"); CheckForInvalidValues(); ResolveValueRelationships(); // Apply translations here to ensure that initial translations are correct when the game starts. // This is done this way to allow StartupActions to run before SimulationParameters are loaded ApplyTranslations(); GD.Print("SimulationParameters are good"); }
public CalculatePopulation(AutoEvoConfiguration configuration, PatchMap map, List <Species> extraSpecies = null, List <Species> excludedSpecies = null, bool collectEnergyInfo = false) { this.configuration = configuration; this.map = map; this.extraSpecies = extraSpecies; this.excludedSpecies = excludedSpecies; this.collectEnergyInfo = collectEnergyInfo; }
private static void RunSimulationStep(SimulationConfiguration parameters, List <Species> species, IEnumerable <KeyValuePair <int, Patch> > patchesToSimulate, Random random, SimulationCache cache, AutoEvoConfiguration autoEvoConfiguration) { foreach (var entry in patchesToSimulate) { // Simulate the species in each patch taking into account the already computed populations SimulatePatchStep(parameters, entry.Value, species.Where(item => parameters.Results.GetPopulationInPatch(item, entry.Value) > 0), random, cache, autoEvoConfiguration); } }
/// <summary> /// Loads the simulation configuration parameters from JSON files /// </summary> private SimulationParameters() { // Compounds are referenced by the other json files so it is loaded first and instance is assigned here instance = this; // Loading the compounds needs a custom JSON deserializer that can load the Compound objects, but the loader // can't always be active because that breaks saving { var compoundDeserializer = new JsonConverter[] { new CompoundLoader(null) }; compounds = LoadRegistry <Compound>( "res://simulation_parameters/microbe_stage/compounds.json", compoundDeserializer); } membranes = LoadRegistry <MembraneType>( "res://simulation_parameters/microbe_stage/membranes.json"); backgrounds = LoadRegistry <Background>( "res://simulation_parameters/microbe_stage/backgrounds.json"); biomes = LoadRegistry <Biome>( "res://simulation_parameters/microbe_stage/biomes.json"); bioProcesses = LoadRegistry <BioProcess>( "res://simulation_parameters/microbe_stage/bio_processes.json"); organelles = LoadRegistry <OrganelleDefinition>( "res://simulation_parameters/microbe_stage/organelles.json"); NameGenerator = LoadDirectObject <NameGenerator>( "res://simulation_parameters/microbe_stage/species_names.json"); musicCategories = LoadRegistry <MusicCategory>("res://simulation_parameters/common/music_tracks.json"); helpTexts = LoadRegistry <HelpTexts>("res://simulation_parameters/common/help_texts.json"); inputGroups = LoadListRegistry <NamedInputGroup>("res://simulation_parameters/common/input_options.json"); autoEvoConfiguration = LoadDirectObject <AutoEvoConfiguration>("res://simulation_parameters/common/autoevo_parameters.json"); gallery = LoadRegistry <Gallery>("res://simulation_parameters/common/gallery.json"); GD.Print("SimulationParameters loading ended"); CheckForInvalidValues(); ResolveValueRelationships(); GD.Print("SimulationParameters are good"); }
/// <summary> /// The heart of the simulation that handles the processed parameters and calculates future populations. /// </summary> private static void SimulatePatchStep(SimulationConfiguration simulationConfiguration, Patch patch, IEnumerable <Species> genericSpecies, Random random, SimulationCache cache, AutoEvoConfiguration autoEvoConfiguration) { _ = random; var populations = simulationConfiguration.Results; bool trackEnergy = simulationConfiguration.CollectEnergyInformation; // This algorithm version is for microbe species var species = genericSpecies.Select(s => (MicrobeSpecies)s).ToList(); // Skip if there aren't any species in this patch if (species.Count < 1) { return; } var energyBySpecies = new Dictionary <MicrobeSpecies, float>(); foreach (var currentSpecies in species) { energyBySpecies[currentSpecies] = 0.0f; } bool strictCompetition = autoEvoConfiguration.StrictNicheCompetition; var niches = new List <FoodSource> { new EnvironmentalFoodSource(patch, Sunlight, Constants.AUTO_EVO_SUNLIGHT_ENERGY_AMOUNT), new CompoundFoodSource(patch, Glucose), new CompoundFoodSource(patch, HydrogenSulfide), new CompoundFoodSource(patch, Iron), new ChunkFoodSource(patch, "marineSnow"), new ChunkFoodSource(patch, "ironSmallChunk"), new ChunkFoodSource(patch, "ironBigChunk"), }; foreach (var currentSpecies in species) { niches.Add(new HeterotrophicFoodSource(patch, currentSpecies)); } foreach (var niche in niches) { // If there isn't a source of energy here, no need for more calculations if (niche.TotalEnergyAvailable() <= MathUtils.EPSILON) { continue; } var fitnessBySpecies = new Dictionary <MicrobeSpecies, float>(); var totalNicheFitness = 0.0f; foreach (var currentSpecies in species) { float thisSpeciesFitness; if (strictCompetition) { // Softly enforces https://en.wikipedia.org/wiki/Competitive_exclusion_principle // by exaggerating fitness differences thisSpeciesFitness = Mathf.Max(Mathf.Pow(niche.FitnessScore(currentSpecies, cache), 2.5f), 0.0f); } else { thisSpeciesFitness = Mathf.Max(niche.FitnessScore(currentSpecies, cache), 0.0f); } fitnessBySpecies[currentSpecies] = thisSpeciesFitness; totalNicheFitness += thisSpeciesFitness; } // If no species can get energy this way, no need for more calculations if (totalNicheFitness <= MathUtils.EPSILON) { continue; } foreach (var currentSpecies in species) { var energy = fitnessBySpecies[currentSpecies] * niche.TotalEnergyAvailable() / totalNicheFitness; // If this species can't gain energy here, don't count it (this also prevents it from appearing // in food sources (if that's not what we want), if the species doesn't use this food source if (energy <= MathUtils.EPSILON) { continue; } energyBySpecies[currentSpecies] += energy; if (trackEnergy) { populations.AddTrackedEnergyForSpecies(currentSpecies, patch, niche, fitnessBySpecies[currentSpecies], energy, totalNicheFitness); } } } foreach (var currentSpecies in species) { var energyBalanceInfo = cache.GetEnergyBalanceForSpecies(currentSpecies, patch); // Modify populations based on energy var newPopulation = (long)(energyBySpecies[currentSpecies] / energyBalanceInfo.FinalBalanceStationary); if (trackEnergy) { populations.AddTrackedEnergyConsumptionForSpecies(currentSpecies, patch, newPopulation, energyBySpecies[currentSpecies], energyBalanceInfo.FinalBalanceStationary); } // TODO: this is a hack for now to make the player experience better, try to get the same rules working // for the player and AI species in the future. if (currentSpecies.PlayerSpecies) { // Severely penalize a species that can't osmoregulate if (energyBalanceInfo.FinalBalanceStationary < 0) { newPopulation /= 10; } } else { // Severely penalize a species that can't move indefinitely if (energyBalanceInfo.FinalBalance < 0) { newPopulation /= 10; } } // Can't survive without enough population if (newPopulation < Constants.AUTO_EVO_MINIMUM_VIABLE_POPULATION) { newPopulation = 0; } populations.AddPopulationResultForSpecies(currentSpecies, patch, newPopulation); } }
public ForceExtinction(List <Patch> patches, AutoEvoConfiguration configuration) { this.patches = patches; this.configuration = configuration; }