/// <summary> /// Construct a new creeature from the two parent creatures. /// Really it is just a randomly chosen value from either creature which is mutated slightly to make it more unique. /// </summary> /// <param name="c1"></param> /// <param name="c2"></param> /// <param name="rate"></param> /// <returns></returns> public static ChromosomeComposition Crossover(ChromosomeComposition c1, ChromosomeComposition c2, double rate) { var newChromsome = new ChromosomeComposition(); // Crossover colour var chromosome1Colour = c1.GetColour(); var chromosome2Colour = c2.GetColour(); var r = .5F * chromosome1Colour.r + .5F * chromosome2Colour.r; var g = .5F * chromosome1Colour.g + .5F * chromosome2Colour.g; var b = .5F * chromosome1Colour.b + .5F * chromosome2Colour.b; newChromsome.SetColour(r, g, b); var chromosome1LimbColour = c1.GetLimbColour(); var chromosome2LimbColour = c2.GetLimbColour(); r = .5F * chromosome1LimbColour.r + .5F * chromosome2LimbColour.r; g = .5F * chromosome1LimbColour.g + .5F * chromosome2LimbColour.g; b = .5F * chromosome1LimbColour.b + .5F * chromosome2LimbColour.b; // Assign new colour newChromsome.SetLimbColour(r, g, b); // Crossover limbs var chromome1Branches = c1.Branches; var chromosome2Branches = c2.Branches; ArrayList newBranches; // Select the parent from which the child will take its limb structure var randomSelect = Random.Range(0, 2); // 1 or the other ArrayList chosenParentBranches; if (randomSelect == 0) { newBranches = chromome1Branches; chosenParentBranches = chromosome2Branches; } else { newBranches = chromosome2Branches; chosenParentBranches = chromome1Branches; } randomSelect = Random.Range(0, 2); // If 0 select parent 1 branch scale, if 1 select parent 2 branch scale newChromsome.SetRootScale(randomSelect == 0 ? c1.GetRootScale() : c2.GetRootScale()); // Select attributes from the selected parents limbs to assign to child limbs newChromsome.NumRecurrences = new int[newBranches.Count]; for (var i = 0; i < newBranches.Count; i++) { var parentLimbs = (ArrayList)newBranches[i]; newChromsome.NumRecurrences[i] = parentLimbs.Count; for (var j = 1; j < parentLimbs.Count; j++) { var parentAttributes = (ArrayList)parentLimbs[j]; // Select random segment from parent creature var index = Random.Range(0, chosenParentBranches.Count); var otherParentLimbs = (ArrayList)chosenParentBranches[index]; index = Random.Range(0, otherParentLimbs.Count); var otherParentAttributes = (ArrayList)otherParentLimbs[index]; // Get parent scale var parentScale = (Vector3)parentAttributes[1]; var otherParentScale = (Vector3)otherParentAttributes[1]; for (var s = 0; s < 3; s++) { _rand = Rnd.NextDouble(); if (_rand < rate) { parentScale[s] = otherParentScale[s]; } } // Select random segment from other creature otherParentLimbs = (ArrayList)chosenParentBranches[Random.Range(0, chosenParentBranches.Count)]; otherParentAttributes = (ArrayList)otherParentLimbs[Random.Range(0, otherParentLimbs.Count)]; var parentPosition = (Vector3)parentAttributes[0]; var otherParentPosition = (Vector3)otherParentAttributes[0]; for (var p = 0; p < 3; p++) { _rand = Rnd.NextDouble(); if (_rand < rate) { parentPosition[p] = otherParentPosition[p]; } } } newBranches[i] = parentLimbs; newChromsome.NumBranches = newBranches.Count; } // Crossover frequency and amplitude newChromsome.JointAmplitude = c1.JointAmplitude; newChromsome.JointFrequency = c1.JointFrequency; newChromsome.JointPhase = c1.JointPhase; _rand = Rnd.NextDouble(); if (_rand < 0.5f) { newChromsome.JointAmplitude = c2.JointAmplitude; } _rand = Rnd.NextDouble(); if (_rand < 0.5f) { newChromsome.JointFrequency = c2.JointFrequency; } _rand = Rnd.NextDouble(); if (_rand < 0.5f) { newChromsome.JointPhase = c2.JointPhase; } { } _rand = Rnd.NextDouble(); // New creature hunger point is one of either the two parents hunger points newChromsome.HungerPoint = _rand < 0.5f ? c2.HungerPoint : c1.HungerPoint; // Assign new branches newChromsome.SetBranches(newBranches); return(newChromsome); }
private GameObject SetupSubLimb(int i, int j, List <GameObject> actualLimbs, JointDrive angXDrive, out Limb limbScript) { var limb = GameObject.CreatePrimitive(PrimitiveType.Cube); limb.layer = LayerMask.NameToLayer("Creature"); limb.name = "limb_" + i + "_" + j; limb.transform.parent = _t; actualLimbs.Add(limb); limbScript = limb.AddComponent <Limb>(); var attributes = (ArrayList)_limbs[j]; limbScript.SetScale((Vector3)attributes[1]); limbScript.SetColour(ChromosomeComposition.GetLimbColour()); if (j == 0) { limbScript.SetPosition((Vector3)attributes[0]); limb.transform.LookAt(Root.transform); } else { limbScript.SetPosition(actualLimbs[j - 1].transform.localPosition); limb.transform.LookAt(Root.transform); limb.transform.Translate(0, 0, -actualLimbs[j - 1].transform.localScale.z); } limb.AddComponent <Rigidbody>(); limb.AddComponent <BoxCollider>(); limb.GetComponent <Collider>().material = (PhysicMaterial)Resources.Load("Physics Materials/Creature"); var joint = limb.AddComponent <ConfigurableJoint>(); joint.axis = new Vector3(0.5F, 0F, 0F); joint.anchor = new Vector3(0F, 0F, 0.5F); if (j == 0) { joint.connectedBody = Root.GetComponent <Rigidbody>(); } else { joint.connectedBody = actualLimbs[j - 1].GetComponent <Rigidbody>(); } limb.GetComponent <Rigidbody>().drag = 1F; _joints.Add(joint); joint.xMotion = ConfigurableJointMotion.Locked; joint.yMotion = ConfigurableJointMotion.Locked; joint.zMotion = ConfigurableJointMotion.Locked; joint.angularXMotion = ConfigurableJointMotion.Free; joint.angularYMotion = ConfigurableJointMotion.Free; joint.angularZMotion = ConfigurableJointMotion.Free; angXDrive.positionSpring = 7F; angXDrive.maximumForce = 100000000F; joint.angularXDrive = angXDrive; joint.angularYZDrive = angXDrive; limb.GetComponent <Rigidbody>().SetDensity(1F); return(limb); }
public static ChromosomeComposition Mutate(ChromosomeComposition currentCreatureComposition, double mutationRate, float mutationFactor) { // Mutate colour var newColour = new float[3]; // new 3 bit colour, r, g, and b var currentColour = currentCreatureComposition.GetColour(); // get the current colour of the creature // map current colours rgb values to the new colour newColour[0] = currentColour.r; newColour[1] = currentColour.g; newColour[2] = currentColour.b; for (var i = 0; i < 3; i++) { _rand = Rnd.NextDouble(); if (_rand < mutationRate) { newColour[i] += RandomiseThisGene(mutationFactor); } } // Assign new colour to this creature currentCreatureComposition.SetColour(newColour[0], newColour[1], newColour[2]); // Mutate root scale var currentRootScale = currentCreatureComposition.GetRootScale(); // Check that the current scale (of x, y and z) is currently greater than 1 if (currentRootScale.x > 1F && currentRootScale.y > 1F && currentRootScale.z > 1F) {// Create new 3 bit root scale (x,y, and z) var newRootScale = new float[3]; newRootScale[0] = currentRootScale.x; newRootScale[1] = currentRootScale.y; newRootScale[2] = currentRootScale.z; for (var i = 0; i < 3; i++) { _rand = Rnd.NextDouble(); if (_rand < mutationRate) { // Randomise scale newRootScale[i] += RandomiseThisGene(mutationFactor); } } // Assign new root scale to creature var rootScale = new Vector3(newRootScale[0], newRootScale[1], newRootScale[2]); currentCreatureComposition.SetRootScale(rootScale); } // Mutate limbs colour currentColour = currentCreatureComposition.GetLimbColour(); newColour[0] = currentColour.r; newColour[1] = currentColour.g; newColour[2] = currentColour.b; for (var i = 0; i < 3; i++) { _rand = Rnd.NextDouble(); if (_rand < mutationRate) { newColour[i] += RandomiseThisGene(mutationFactor); } } // Assign new colour to creature currentCreatureComposition.SetLimbColour(newColour[0], newColour[1], newColour[2]); var currentBranches = currentCreatureComposition.Branches; foreach (var branch in currentBranches) {// get a list of limbs var currentLimbs = (ArrayList)branch; foreach (var limb in currentLimbs) { var limbs = (ArrayList)limb; var v = (Vector3)limbs[1]; for (var k = 0; k < 3; k++) { _rand = Rnd.NextDouble(); if (_rand < mutationRate) { v[k] += RandomiseThisGene(mutationFactor); } } } } // mutate base frequency and amplitude _rand = Rnd.NextDouble(); if (_rand < mutationRate) { currentCreatureComposition.JointAmplitude += RandomiseThisGene(mutationFactor); } _rand = Rnd.NextDouble(); if (_rand < mutationRate) { currentCreatureComposition.JointFrequency += RandomiseThisGene(mutationFactor); } _rand = Rnd.NextDouble(); if (_rand < mutationRate) { currentCreatureComposition.JointPhase += RandomiseThisGene(mutationFactor); } _rand = Rnd.NextDouble(); if (_rand < mutationRate) { currentCreatureComposition.HungerPoint += RandomiseThisGene(mutationFactor); } currentCreatureComposition.SetBranches(currentBranches); return(currentCreatureComposition); }