/* Creature - Contains the workings for the Creature class *///////////////////////////////////////////////////////// #include #include #include "Creature.h" #include "Genome.h" #include "Gene.h" #include "Neuron.h" // Member Functions ////////////////////////////////////////////////////// //createRepresentation - Transforms the herited genome data into a real, usable // representation of the creature void Creature::createRepresentation() { // Sort out the genome ////////////////////////////////////////////////// //Clear the existing information m_genomeRep.clearGenes(); //Recurse through our existing genome walkGenome(0, -1, 0, 0); // Fix up the neural connections ////////////////////////////////////////////////// //Walk through our new representation genome for (u32 i=0; i < m_genomeRep.size(); ++i) { //Walk through the neuron list Gene &rep = m_genomeRep.at(i); for (u32 j=0; j < rep.m_neurons.size(); ++j) { //Examine the connections Neuron &neur = rep.m_neurons.at(j); for (u32 k=0; k < neur.m_conns.size(); ++k) { //Examine the connections Neuron::Connection &con = neur.m_conns.at(k); //If the connection comes from the rep gene's original gene, //then we must check to see if it's being recursively duplicated, //and if so check the genetic info to determine how to deal with //the connection bool bFound = false; bool bRecursive = false; if (con.geneID == rep.m_representsID) { //If our gene is the root limb, we're recursing, //and the order of recursion is correct if ((rep.m_parentID != -1) && (rep.m_representsID == m_genome[rep.m_parentID]) && { //It's recursive! bRecursive = true; //If it's recursing from the parent.. if (con.t_rec == TYPE_PARENT) { //.. we've got it! con.geneID = rep.m_parentID; bFound = true; } } //Look through our other representitive genes for (u32 x=0; x < m_genomeRep.size(); ++x) { //Get our reference Gene &reptwo = m_genomeRep.at(x); //If we're the parent, and we both represent the same //heritable gene.. if (reptwo.m_parentID == rep.m_id && reptwo.m_representsID == rep.representsID) { //It's recursive! bRecursive = true; //If it's recursing from the child.. if (con.t_rec == TYPE_CHILD) { //.. we've got it! con.geneID = reptwo.m_id; bFound = true; } } } //If there's definitely a recursion that hasn't been found yet, if (bRecursive && !bFound) { //If it's a self-recursion then it's pretty obvious what to do if (con.t_rec == TYPE_SELF) con.geneID = rep.m_id; bFound = true; } else if (!bFound) { con.geneID = rep.m_id; bFound = true; } } else { //If the connection is from the root gene, and we're not recursive if (con.geneID == 0 && rep.m_representsID != m_genomeRep[rep.m_parentID].m_representsID) { //We don't have to worry about fixing the connection bFound = true; } //If we're the root gene if (rep.m_id == 0) { //Look through all rep genes for (u32 x=0; x < m_genomeRep.size(); ++x) { //Get our reference Gene &reptwo = m_genomeRep.at(x); //If this gene isn't recursed from the parent, // and our connection is represented by him if (reptwo.m_representsID != m_genomeRep[reptwo.m_parentID].m_representsID && con.geneID == reptwo.m_representsID) { //Got it! con.geneID = reptwo.m_id; bFound = true; } } } //If we have a parent, and the neuron connection points to him if (rep.m_parentID != -1 && con.geneID == m_genomeRep[rep.m_parentID].m_representsID) { //Found it con.geneID = rep.m_parentID; bFound = true; } //Look through our other representitive genes for (u32 x=0; x < m_genomeRep.size(); ++x) { //Get our reference Gene &reptwo = m_genomeRep.at(x); //Look for child genes that represent our connection if (reptwo.m_parentID == rep.m_id && con.geneID == reptwo.m_representsID) { //Got it! con.geneID = reptwo.m_id; bFound = true; } } } //Make sure the connection is valid assert(con.geneID != -1, "Unable to find connection's owner gene."); //Have we found the original connector? if (!bFound) //Looks like we'll have to remove him :( neur.m_conns.erase(m_conns[k--]); } } } } //walkGenome - Internal recursive function to walk the genome and construct the representation void Creature::walkGenome(s32 idx, s32 parentID, s32 nRecursion, s32 symmetry) { // Construct new representative gene ////////////////////////////////////////////////// Gene limbrep; Gene &parent = m_genomeRep[parentID]; //Populate the new gene limbrep = m_genome.at(idx); limbrep.m_representsID = limbrep.m_id; limbrep.m_parentID = parentID; //If this gene is involved in symmetry if (symmetry) limbrep.symmetrised = 1 - parent.symmetrised; else limbrep.symmetrised = parent.symmetrised; //Flip the emergent angle if (limbrep.symmetrised) limbrep.alpha *= -1; //Is this a recursive gene? if (parent.m_representsID == limbrep.m_id) { //limbrep.alpha = limbrep.alpharec / 4.0; //limbrep.beta = limbrep.betarec / 4.0; limbrep.alpha = limbrep.beta = 0; if (limbrep.symmetrised) limbrep.alpha *= -1; } //We can now add the new representative gene s32 limbID = m_genomeRep.addGene(limbrep); ////////////////////////////////////////////////// // Recurse through child genes ////////////////////////////////////////////////// //Look through the original genome for (u32 i=0; i < m_genome.size(); ++i) { //If gene is a child of this iteration.. Gene &it = m_genome.at(i); if (it.m_parentID == limbrep.m_id && !it.terminal) { //Process it! walkGenome(i, limbID, it.m_recursion, 0); //Draw the reflection too if (it.m_reflection == true) walkGenome(i, limbID, it.m_recursion, 1); } } //Draw our recursions if (nRecursion > 0 && (parentID != -1)) { //Walk it walkGenome(idx, limbID, nRecursion - 1, 0); limbID = m_genomeRep.m_curGeneID - 1; } //Look through the original genome for (u32 i=0; i < m_genome.size(); ++i) { //If gene is a child of this iteration.. Gene &it = m_genome.at(i); if (it.m_parentID == limbrep.m_id && it.terminal && !nRecursion) { //Process it! walkGenome(i, limbID, it.m_recursion, 0); //Draw the reflection too if (it.m_reflection == true) walkGenome(i, limbID, it.m_recursion, 1); } } }