Exemple #1
0
    /// <summary>
    ///   Creates a mutated version of parentOrganelles in organelles
    /// </summary>
    private void MutateMicrobeOrganelles(OrganelleLayout <OrganelleTemplate> parentOrganelles,
                                         OrganelleLayout <OrganelleTemplate> organelles, bool isBacteria)
    {
        var nucleus = SimulationParameters.Instance.GetOrganelleType("nucleus");

        for (var iteration = 0; iteration < 10; iteration++)
        {
            organelles.Clear();

            // Delete or replace an organelle randomly
            for (int i = 0; i < parentOrganelles.Count; i++)
            {
                bool copy = true;

                var organelle = parentOrganelles[i];

                if (parentOrganelles.Count < 2)
                {
                    // Removing last organelle would be silly
                }
                else if (organelle.Definition != nucleus)
                {
                    // Chance to replace or remove if not a nucleus

                    if (random.Next(0.0f, 1.0f) < Constants.MUTATION_DELETION_RATE)
                    {
                        copy = false;
                    }
                    else if (random.Next(0.0f, 1.0f) < Constants.MUTATION_REPLACEMENT_RATE)
                    {
                        copy = false;

                        var replacer = new OrganelleTemplate(GetRandomOrganelle(isBacteria),
                                                             organelle.Position, organelle.Orientation);

                        // The replacing organelle might not fit at the same position
                        try
                        {
                            organelles.Add(replacer);
                        }
                        catch (ArgumentException)
                        {
                            // Couldn't replace it
                            copy = true;
                        }
                    }
                }

                if (!copy)
                {
                    continue;
                }

                // Copy the organelle
                try
                {
                    organelles.Add((OrganelleTemplate)organelle.Clone());
                }
                catch (ArgumentException)
                {
                    // Add the organelle randomly back to the list to make
                    // sure we don't throw it away
                    AddNewOrganelle(organelles, organelle.Definition);
                }
            }

            // Can add up to 6 new organelles (Which should allow AI to catch up to player more
            // We can insert new organelles at the end of the list
            if (random.Next(0.0f, 1.0f) < Constants.MUTATION_CREATION_RATE)
            {
                AddNewOrganelle(organelles, GetRandomOrganelle(isBacteria));
            }

            /*
             * Probability of mutation occuring 5 time(s) = 0.15 = 1.0E-5
             * Probability of mutation NOT occuring = (1 - 0.1)5 = 0.59049
             * Probability of mutation occuring = 1 - (1 - 0.1)5 = 0.40951
             */

            // We can insert new organelles at the end of the list
            for (int n = 0; n < 5; ++n)
            {
                if (random.Next(0.0f, 1.0f) < Constants.MUTATION_EXTRA_CREATION_RATE)
                {
                    AddNewOrganelle(organelles, GetRandomOrganelle(isBacteria));
                }
            }

            if (isBacteria)
            {
                if (random.Next(0.0f, 100.0f) <= Constants.MUTATION_BACTERIA_TO_EUKARYOTE)
                {
                    AddNewOrganelle(organelles, nucleus);
                }
            }

            // Disallow creating empty species as that throws an exception when trying to spawn
            if (organelles.Count < 1)
            {
                // Add the first parent species organelle
                AddNewOrganelle(organelles, parentOrganelles[0].Definition);

                // If still empty, copy the first organelle of the parent
                if (organelles.Count < 1)
                {
                    organelles.Add((OrganelleTemplate)parentOrganelles[0].Clone());
                }
            }

            // Try again if the mutation has islands
            if (organelles.GetIslandHexes().Count == 0)
            {
                return;
            }
        }

        GD.PrintErr("Could not create a valid mutation after 10 retries.");
    }
    /// <summary>
    ///   Creates a mutated version of parentOrganelles in organelles
    /// </summary>
    private void MutateMicrobeOrganelles(OrganelleLayout <OrganelleTemplate> parentOrganelles,
                                         OrganelleLayout <OrganelleTemplate> mutatedOrganelles, bool isBacteria)
    {
        var nucleus = SimulationParameters.Instance.GetOrganelleType("nucleus");

        for (var iteration = 0; iteration < 10; iteration++)
        {
            mutatedOrganelles.Clear();

            // Chance to replace each organelle randomly
            foreach (var parentOrganelle in parentOrganelles)
            {
                var organelle = (OrganelleTemplate)parentOrganelle.Clone();

                // Chance to replace or remove if not a nucleus
                if (organelle.Definition != nucleus)
                {
                    if (random.Next(0.0f, 1.0f) < Constants.MUTATION_DELETION_RATE / Math.Sqrt(parentOrganelles.Count))
                    {
                        // Don't copy over this organelle, removing this one from the new species
                        continue;
                    }

                    if (random.Next(0.0f, 1.0f) < Constants.MUTATION_REPLACEMENT_RATE)
                    {
                        organelle = new OrganelleTemplate(GetRandomOrganelle(isBacteria),
                                                          organelle.Position, organelle.Orientation);
                    }
                }

                // Copy the organelle
                try
                {
                    mutatedOrganelles.Add(organelle);
                }
                catch (ArgumentException)
                {
                    // Add the organelle randomly back to the list to make
                    // sure we don't throw it away
                    AddNewOrganelle(mutatedOrganelles, organelle.Definition);
                }
            }

            // We can insert new organelles at the end of the list
            for (int i = 0; i < 6; ++i)
            {
                if (random.Next(0.0f, 1.0f) < Constants.MUTATION_CREATION_RATE)
                {
                    AddNewOrganelle(mutatedOrganelles, GetRandomOrganelle(isBacteria));
                }
            }

            if (isBacteria)
            {
                if (random.Next(0.0f, 1.0f) <= Constants.MUTATION_BACTERIA_TO_EUKARYOTE)
                {
                    AddNewOrganelle(mutatedOrganelles, nucleus);
                }
            }

            // Disallow creating empty species as that throws an exception when trying to spawn
            if (mutatedOrganelles.Count < 1)
            {
                // Add the first parent species organelle
                AddNewOrganelle(mutatedOrganelles, parentOrganelles[0].Definition);

                // If still empty, copy the first organelle of the parent
                if (mutatedOrganelles.Count < 1)
                {
                    mutatedOrganelles.Add((OrganelleTemplate)parentOrganelles[0].Clone());
                }
            }

            // If the mutation has no islands, we can use this iteration
            if (mutatedOrganelles.GetIslandHexes().Count == 0)
            {
                return;
            }
        }

        GD.PrintErr("Could not create a valid mutation after 10 retries.");
    }