private void CreateFirstGeneration() { population = new List <ClimberGenetics>(PopulationSize); for (int i = 0; i < PopulationSize; i++) { ClimberGenetics genetics = new ClimberGenetics(); int numActions = Random.Range(MinActions, MaxActions + 1); BodyShapeGene bodyShapeGene = new BodyShapeGene( Random.Range(MinBodyWidth, MaxBodyWidth), Random.Range(MinBodyHeight, MaxBodyHeight)); Gene previousAction = null; genetics.Chromosome.Add(bodyShapeGene); for (int j = 0; j < numActions; j++) { Gene actionGene = CreateNewActionGene(genetics, previousAction); previousAction = actionGene; genetics.Chromosome.Add(actionGene); } population.Add(genetics); } Logger.Add("Created random genetic information for a population of " + population.Count); }
private Gene CreateNewActionGene(ClimberGenetics genetics, Gene previousGene) { Gene actionGene = null; GeneType actionType = RandomGeneType(new[] { GeneType.GrabAction, GeneType.ReleaseAction, GeneType.SwingAction, GeneType.NonAction, }); if (actionType == GeneType.GrabAction) { Vector3 localPoint = Vector3.zero; int index = Random.Range(0, 4); if (index == 0) { localPoint = new Vector3(-0.5f, -0.5f, 0f); } else if (index == 1) { localPoint = new Vector3(0.5f, -0.5f, 0f); } else if (index == 2) { localPoint = new Vector3(0.5f, 0.5f, 0f); } else if (index == 3) { localPoint = new Vector3(-0.5f, 0.5f, 0f); } actionGene = new GrabActionGene(localPoint); } else if (actionType == GeneType.ReleaseAction) { actionGene = new ReleaseActionGene(); } else if (actionType == GeneType.SwingAction) { BodyShapeGene bodyShapeGene = (BodyShapeGene)genetics.Chromosome[0]; Vector3 localApplyAtPoint = new Vector3( Random.Range(-bodyShapeGene.Width * 0.5f, bodyShapeGene.Width * 0.5f), Random.Range(-bodyShapeGene.Height * 0.5f, bodyShapeGene.Height * 0.5f), 0f); int direction = Random.Range(0, 2) == 0 ? -1 : 1; float strength = Random.Range(MinSwingStrength, MaxSwingStrength); actionGene = new SwingActionGene(localApplyAtPoint, direction, strength); } else if (actionType == GeneType.NonAction) { actionGene = new NonActionGene(Random.Range(MinNonActionTime, MaxNonActionTime)); } return(actionGene); }
public ClimberGenetics Copy() { ClimberGenetics copy = new ClimberGenetics(); foreach (Gene gene in Chromosome) { copy.Chromosome.Add(gene.Copy()); } copy.FitnessScore = FitnessScore; return(copy); }
private void StartFitnessTest() { GameObject climberObj; Climber climber; ClimberGenetics genetics = population[currentPopulationIndex]; BodyShapeGene bodyShapeGene = (BodyShapeGene)genetics.Chromosome[0]; isRunningFitnessTest = true; climberObj = Instantiate <GameObject>(ClimberPrefab); climberObj.transform.parent = objectsContainer; climberObj.transform.position = SpawnPosition - new Vector3(0f, bodyShapeGene.Height * 0.5f, 0f); climber = climberObj.GetComponentInChildren <Climber>(); climber.Genetics = genetics; currentClimber = climber; currentClimberObj = climberObj; }
private void MutateGene(ClimberGenetics genetics, Gene gene) { if (gene.Type == GeneType.BodyShape) { BodyShapeGene bodyShapeGene = (BodyShapeGene)gene; bodyShapeGene.Width += bodyShapeGene.Width * Random.Range(-MutationStrength, MutationStrength); bodyShapeGene.Height += bodyShapeGene.Height * Random.Range(-MutationStrength, MutationStrength); } else if (gene.Type == GeneType.GrabAction) { if (Random.Range(0f, 1f) < MutationStrength) { GrabActionGene grabActionGene = (GrabActionGene)gene; Vector3 localPoint = Vector3.zero; int index = Random.Range(0, 4); if (index == 0) { localPoint = new Vector3(-0.5f, -0.5f, 0f); } else if (index == 1) { localPoint = new Vector3(0.5f, -0.5f, 0f); } else if (index == 2) { localPoint = new Vector3(0.5f, 0.5f, 0f); } else if (index == 3) { localPoint = new Vector3(-0.5f, 0.5f, 0f); } grabActionGene.LocalPoint = localPoint; } } else if (gene.Type == GeneType.ReleaseAction) { // No properties to mutate } else if (gene.Type == GeneType.SwingAction) { SwingActionGene swingActionGene = (SwingActionGene)gene; BodyShapeGene bodyShapeGene = (BodyShapeGene)genetics.Chromosome[0]; float localX = swingActionGene.LocalPoint.x + swingActionGene.LocalPoint.x * Random.Range(-MutationStrength, MutationStrength); float localY = swingActionGene.LocalPoint.y + swingActionGene.LocalPoint.y * Random.Range(-MutationStrength, MutationStrength); swingActionGene.LocalPoint = new Vector3( Mathf.Clamp(localX, -bodyShapeGene.Width * 0.5f, bodyShapeGene.Width * 0.5f), Mathf.Clamp(localY, -bodyShapeGene.Height * 0.5f, bodyShapeGene.Height * 0.5f), swingActionGene.LocalPoint.z); if (Random.Range(0f, 1f) < MutationStrength) { swingActionGene.Direction = Random.Range(0, 2) == 0 ? -1 : 1; } swingActionGene.Strength = Mathf.Clamp( swingActionGene.Strength + swingActionGene.Strength * Random.Range(-MutationStrength, MutationStrength), MinSwingStrength, MaxSwingStrength); } else if (gene.Type == GeneType.NonAction) { NonActionGene nonActionGene = (NonActionGene)gene; nonActionGene.Time = Mathf.Clamp( nonActionGene.Time + nonActionGene.Time * Random.Range(-MutationStrength, MutationStrength), MinNonActionTime, MaxNonActionTime); } }
private void CreateNextGeneration() { List <ClimberGenetics> newPopulation = new List <ClimberGenetics>(PopulationSize); List <ClimberGenetics> sourcePopulation = new List <ClimberGenetics>(population); RouletteWheel rouletteWheel; float averageFitness = 0f; float highestGenFitness = 0f; // Calculate highest and average fitness foreach (ClimberGenetics genetics in population) { averageFitness += genetics.FitnessScore; highestGenFitness = Mathf.Max(highestGenFitness, genetics.FitnessScore); highestFitness = Mathf.Max(highestFitness, genetics.FitnessScore); } averageFitness /= population.Count; // Sort based on fitness (most to least fit) sourcePopulation.Sort((a, b) => { return(a.FitnessScore > b.FitnessScore ? -1 : 1); }); // Before mating... KILL THE WEAK!@$ for (int i = 0; i < NumToKill; i++) { ClimberGenetics deadbeat = sourcePopulation[sourcePopulation.Count - 1]; Logger.Add("Killing individual with a score of: " + deadbeat.FitnessScore.ToString("0.00")); sourcePopulation.Remove(deadbeat); } rouletteWheel = new RouletteWheel(sourcePopulation); // Add survivors to new population newPopulation.AddRange(sourcePopulation); // Let's fuuuuu for (int i = 0; i < NumToKill; i++) { ClimberGenetics parentA = sourcePopulation[i]; ClimberGenetics parentB = null; ClimberGenetics child = null; // Choose a partner (making sure it's not self) while (parentB == null || parentB == parentA) { parentB = rouletteWheel.GetResult(); } // Crossover genes from parents to child if (Random.Range(0f, 1f) < CrossoverRate) { int maxCrossoverIndex = Mathf.Min(parentA.Chromosome.Count, parentB.Chromosome.Count) - 1; int crossoverIndex = Random.Range(0, maxCrossoverIndex + 1); int maxCount = Mathf.Max(parentA.Chromosome.Count, parentB.Chromosome.Count); child = new ClimberGenetics(); for (int j = 0; j < maxCount; j++) { if (j < crossoverIndex) { child.Chromosome.Add(parentA.Chromosome[j]); } else { if (j < parentB.Chromosome.Count) { child.Chromosome.Add(parentB.Chromosome[j]); } } } } else { child = parentA.Copy(); } // Mutate genes foreach (Gene gene in child.Chromosome) { if (Random.Range(0f, 1f) < MutationRate) { MutateGene(child, gene); } } newPopulation.Add(child); } Logger.Add("Average fitness for generation " + currentGeneration + ": " + averageFitness.ToString("0.00")); Logger.Add("Highest fitness for generation " + currentGeneration + ": " + highestGenFitness.ToString("0.00")); Logger.Add("Highest all-time fitness: " + highestFitness.ToString("0.00")); currentGeneration++; population = newPopulation; Logger.Add("Created new genetic information for generation " + currentGeneration); }
public RouletteWheelRange(float min, float max, ClimberGenetics genetics) { Min = min; Max = max; Genetics = genetics; }