Esempio n. 1
0
    /// <summary>
    ///   Resets the organelles in this microbe to match the species definition
    /// </summary>
    public void ResetOrganelleLayout()
    {
        // TODO: It would be much better if only organelles that need
        // to be removed where removed, instead of everything.
        // When doing that all organelles will need to be re-added anyway if this turned from a prokaryote to eukaryote

        if (organelles == null)
        {
            organelles = new OrganelleLayout <PlacedOrganelle>(OnOrganelleAdded,
                                                               OnOrganelleRemoved);
        }
        else
        {
            // Just clear the existing ones
            organelles.Clear();
        }

        foreach (var entry in Species.Organelles.Organelles)
        {
            var placed = new PlacedOrganelle
            {
                Definition  = entry.Definition,
                Position    = entry.Position,
                Orientation = entry.Orientation,
            };

            organelles.Add(placed);
        }

        // Reproduction progress is lost
        allOrganellesDivided = false;

        // Unbind if a colony's master cell removed its binding agent.
        if (Colony != null && Colony.Master == this && !organelles.Any(p => p.IsBindingAgent))
        {
            Colony.RemoveFromColony(this);
        }
    }
Esempio n. 2
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");

        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());
            }
        }
    }
Esempio n. 3
0
    /// <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.");
    }