public override bool Equals(Phenotype phenotype)
 {
     if (phenotype is PhenotypeGroup otherGroup && otherGroup.Phenotypes.Length == phenotypes.Length)
     {
         for (int i = 0; i < phenotypes.Length; i++)
         {
             if (!phenotypes[i].Equals(otherGroup.Phenotypes[i]))
             {
                 return(false);
             }
         }
         return(true);
     }
        public override Phenotype Clone(Phenotype otherParent)
        {
            //Assume to be another phenotype group
            PhenotypeGroup groupParent = (PhenotypeGroup)otherParent;

            Phenotype[] phenotypeClones = new Phenotype[phenotypes.Length];
            for (int i = 0; i < phenotypeClones.Length; i++)
            {
                phenotypeClones[i] = phenotypes[i].Clone(groupParent.Phenotypes[i]);
            }

            return(new PhenotypeGroup(phenotypeClones));
        }
        /// <summary>
        /// Breeds two ModularMembers and produces two children.
        /// </summary>
        /// <param name="parent1">The first parent.</param>
        /// <param name="parent2">The second parent.</param>
        /// <param name="mutationRate">The mutation rate during breeding.</param>
        /// <param name="random">The random to be used while breeding.</param>
        /// <returns>Returns the two children.</returns>
        public static ModularMember[] BreedMembers(ModularMember parent1, ModularMember parent2, double mutationRate, Random random)
        {
            //Ensure breedable
            if (parent1.CanBreedWith(parent2))
            {
                GeneticSequence[] child1Genome = new GeneticSequence[parent1.genome.Length];
                GeneticSequence[] child2Genome = new GeneticSequence[parent1.genome.Length];

                for (int i = 0; i < parent1.genome.Length; i++)
                {
                    GeneticSequence[] crossoverSequences = GeneticSequence.Crossover(parent1.genome[i], parent2.genome[i], random);
                    child1Genome[i] = crossoverSequences[0];
                    child2Genome[i] = crossoverSequences[1];
                }

                //Mutate each genome
                for (int i = 0; i < child1Genome.Length; i++)
                {
                    child1Genome[i] = child1Genome[i].BitwiseMutate(mutationRate, random);
                }
                for (int i = 0; i < child2Genome.Length; i++)
                {
                    child2Genome[i] = child2Genome[i].BitwiseMutate(mutationRate, random);
                }

                ModularMember[]     parents        = new ModularMember[] { parent1, parent2 };
                GeneticSequence[][] childSequences = new GeneticSequence[][] { child1Genome, child2Genome };
                ModularMember[]     children       = new ModularMember[2];
                for (int i = 0; i < children.Length; i++)
                {
                    Phenotype[] phenotypes = new Phenotype[parents[i].phenotypes.Length];
                    for (int j = 0; j < phenotypes.Length; j++)
                    {
                        phenotypes[j] = parents[i].phenotypes[j].Clone(parents[(i + 1) % parents.Length].phenotypes[j]);
                    }

                    children[i] = new ModularMember(phenotypes);
                    children[i].AssignGenome(childSequences[i]);
                }

                return(children);
            }
            else
            {
                throw new Exception("Provided parents are not breedable.");
            }
        }