|
From: Andrew <ber...@gm...> - 2008-09-07 06:00:03
|
Spore has been released! OK, so only a somewhat related peice of news- but
I think I might be going out to buy it tomorrow assuming I can find a copy.
:) Anyone else psyched about it?
The real reason I'm posting to the list to just throw out some thoughts of
mine I've had today regarding some future features of polyworld and the
related design approaches, specifically (or probably more acurately just a
working example) related to the critter genome and genes.
I've been reading a little toay about biological genetics and refreshin my
memory from my High School biology class as to how genes, codons and all
that jazz work and how I can apply that knowledge to build a more flexible
means of storing a critter's genome - maybe not use it as a blueprint, but
just gleen some understanding to maybe think of the data structures
differently.
The data-related things I took from it (or at least adapted from it) are:
* A "gene" would be an arbitrary length series of codons.
* We could optionally include the concept of a chromosome to collect genes
into sets taht get paired up when a new critter is created through mating.
* The genome would contain an arbitrary number of genes- this number
shouldn't fluctuate terribly much.
* Each gene describes some sort of trait... be it the
existance/location/functuion of a neural group or the internal structure of
a neural group, or the means of locomotion, vision an whatever other sensory
mechanisms we can devise.
* I think simply stacking traights into a data structure is too
constrictive- when reading about how proteins are generate from the sequence
of codons, I thought to myself "this seems like a much more flexible, *
natural* way of representing the data. I'm not suggesting we create a DNA
system that generates psuedoproteins and from that collection of proteins we
derive the structure of the organism (though that would be kind of cool), I
guess I'm just inspired (and completely overwhelmed) by the complexity of
the system biology has devised for this.
So heres a data structure somewhat representative of what I'm talking
about... just ignore that there aren't any options on these objects, those
can easily be added later:
typedef Codon unsigned int;
class Gene {
List<Codon> codons;
}
class Genome {
List<Gene> genes;
}
Now, supposing we want some different gene types, we simply decide some
basic rules as to how to convert to and from a sequence of codons to an
actual trait. Not sure what the conversion process would be- it wouldn't
necessarily need to be a 1:1 conversion (a gene can present differently
based on the existance or abence of other genes, and maybe two ifferent
genes could tally up to the same result).
I mean, you can also add the Chromosomes:
class Gene { List<Codon> codons; }
class Chromosome { List<Gene> genes; }
class Genome { List<Chromosome> chromos; }
What I envision with this breakdown is the ability to "plug-in" new stuff in
an object-oriented way:
class Gene {
List<Codon> codons;
public:
/* note: would use smart-pointer here to make cleanup easier */
/* note2: function defined like in java, would really be in a module */
static Gene* getInstance(const string& instanceType) {
Gene* gene;
if instanceType == "basic")
gene = new BasicGene();
else if(instanceType == "freaky")
gene = new FreakyGene();
else if(instanceType == "no mutate")
gene = new ImmutatableGene();
else
throw ("Unknown Gene Type: "+instanceType);
return gene;
}
}
class CritterInput {}
class EyeCritterInput : CritterInput {}
class AntannaCritterInput : CritterInput {}
class CritterOutput {}
class LocomotiveCritterOutput : CritterOutput {}
class ScreamCritterOutput : CritterOutput {}
class MateCritterOutput : CritterOutput {}
In otherwords, create object oriented inherited types... so if in the
critter brain logic you have something like:
class Brain {
// ...
List<CritterInput> inputs;
List<CritterOutput> outputs;
// ....
public:
void updateIO() {
for(List<CritterInput>::iterator itr = inputs.begin(); itr++; itr !=
inputs.end()) {
// do the logic to update the input
}
for(List<CritterOutput>::iterator itr = outputs.begin(); itr++; itr
!= outputs.end()) {
// do the logic to update the output
}
}
}
This way, you can easily add new inputs and outputs that follow a simple
contract and no modifications to the Brain class would even need to be made,
at least not to all the functions. All the type-specific logic would be
housed inside of that class in virtual member functions.
wow, I've really rambled on a bit here...
I know overhauls of the system are out of the question, but I think a system
like this really lends itself to object-oriented concepts with pluggable
logic and such. I guess the only thing I'm trying to accomplish here is to
say that I think we should keep this sort of stuff in the back of our minds-
and furthermore, its been nagging at me and I needed to get it typed out and
thought I'd share. :)
Any feeback would be awesome- even if its something as simple as "your
bloody crazy, come back to earth please...."
Andrew
|