/* 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);
}
}
}