public static Genome Crossover(ref Genome mum, ref Genome dad, GeneticAlgorithm ga) { BestParent bestParent = GetBestParent(ref mum, ref dad); List <int> newPerceptrons = new List <int>(); int curMum = 0; int curDad = 0; ConnectionGene selectedGene = null; Genome newGenome = RecycledGenome(); while (!(curMum == mum.connections.Count && curDad == dad.connections.Count)) { // Dad has more genes if (curMum == mum.connections.Count && curDad != dad.connections.Count) { if (bestParent == BestParent.dad) { selectedGene = dad.GetConnectionGenes()[curDad]; } curDad++; if (selectedGene == null) { continue; } } // Mum has more genes else if (curMum != mum.connections.Count && curDad == dad.connections.Count) { if (bestParent == BestParent.mum) { selectedGene = mum.GetConnectionGenes()[curMum]; } curMum++; if (selectedGene == null) { continue; } } // Mum gene innovation number is lower else if (mum.GetConnectionGenes()[curMum].innovNum < dad.GetConnectionGenes()[curDad].innovNum) { if (bestParent == BestParent.mum) { selectedGene = mum.GetConnectionGenes()[curMum]; } curMum++; if (selectedGene == null) { continue; } } // Dad gene innovation number is lower else if (mum.GetConnectionGenes()[curMum].innovNum > dad.GetConnectionGenes()[curDad].innovNum) { if (bestParent == BestParent.dad) { selectedGene = dad.GetConnectionGenes()[curDad]; } curDad++; if (selectedGene == null) { continue; } } // Both innovation numbers are equal else if (mum.GetConnectionGenes()[curMum].innovNum == dad.GetConnectionGenes()[curDad].innovNum) { if (Random.Range(0f, 1f) > 0.5f) { selectedGene = mum.GetConnectionGenes()[curMum]; } else { selectedGene = dad.GetConnectionGenes()[curDad]; } curDad++; curMum++; } else { Debug.Log("wtf"); } if (selectedGene == null) { Debug.Log("Weird"); continue; } if (newGenome.connectionGeneIndex == 0) { newGenome.AddConnectionGeneGene(new ConnectionGene(selectedGene)); } else { if (newGenome.connections[newGenome.connectionGeneIndex - 1].innovNum != selectedGene.innovNum) { newGenome.AddConnectionGeneGene(new ConnectionGene(selectedGene)); } } newPerceptrons = AddPercepID(selectedGene.from, newPerceptrons); newPerceptrons = AddPercepID(selectedGene.to, newPerceptrons); } newPerceptrons.Sort(); for (int i = 0; i < GA_Parameters.inputs + 1; i++) { newGenome = ga.innovations.CreateNeuronFromID(i, newGenome); } for (int i = 0; i < GA_Parameters.outputs; i++) { newGenome = ga.innovations.CreateNeuronFromID(GA_Parameters.inputs + 1 + i, newGenome); } for (int i = 0; i < newPerceptrons.Count; i++) { newGenome = ga.innovations.CreateNeuronFromID(newPerceptrons[i], newGenome); } MutParameters mutPar = new MutParameters(mum, dad); newGenome.ID = ga.nextGenomeID; newGenome.inputs = mum.inputs; newGenome.outputs = mum.outputs; newGenome.mutPar = mutPar; ga.nextGenomeID++; newGenome.FinishGenome(); return(newGenome); }