コード例 #1
0
    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);
    }
コード例 #2
0
ファイル: GameWorld.cs プロジェクト: MaysaChan/Thrive
    /// <summary>
    ///   Creates an empty species object
    /// </summary>
    public MicrobeSpecies NewMicrobeSpecies()
    {
        var species = new MicrobeSpecies(++speciesIdCounter);

        worldSpecies[species.ID] = species;
        return(species);
    }
コード例 #3
0
        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);
        }
コード例 #4
0
ファイル: FoodSource.cs プロジェクト: Shupsta/Thrive
        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);
        }
コード例 #5
0
    /// <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);
    }
コード例 #6
0
 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;
 }
コード例 #7
0
ファイル: RunResults.cs プロジェクト: Shupsta/Thrive
        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;
        }
コード例 #8
0
    /// <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();
    }
コード例 #9
0
ファイル: GameWorld.cs プロジェクト: MaysaChan/Thrive
    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));
    }
コード例 #10
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);
            }
        }
    }
コード例 #11
0
    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);
    }
コード例 #12
0
    /// <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);
    }
コード例 #13
0
    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);
    }
コード例 #14
0
    /// <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);
    }
コード例 #15
0
ファイル: RunResults.cs プロジェクト: Shupsta/Thrive
        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(),
            };
        }
コード例 #16
0
        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);
        }
コード例 #17
0
ファイル: SpawnItem.cs プロジェクト: Gwen-Benzschawel/Thrive
 public MicrobeItem(MicrobeSpecies species, MicrobeSpawner microbeSpawner)
 {
     this.species   = species;
     MicrobeSpawner = microbeSpawner;
 }
コード例 #18
0
    /// <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);
    }
コード例 #19
0
    /// <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);
    }
コード例 #20
0
    /// <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);
    }