class genome { creature parent=null; gene strain[]; int strainLength; String strainKey; genome(String filename,creature p) { parent=p; String lines[] = loadStrings(filename); strainLength=parent.amount; strain=new gene[strainLength]; for(int i=0;i<strain.length;i++) { String parse[]=split(lines[2+i]); float repeat=Float.parseFloat(parse[0]); float heading=Float.parseFloat(parse[1]); float distance=Float.parseFloat(parse[2]); float neuronWeight=Float.parseFloat(parse[3]); float neuronPower=Float.parseFloat(parse[4]); boolean bidirectional=boolean(Float.parseFloat(parse[5])); float rkey=Float.parseFloat(parse[6]); strain[i]=new gene(i,int(repeat),int(heading),distance,neuronWeight,neuronPower,bidirectional,int(rkey)); } for(int s=0;s<strain.length;s++) { String parse[]=split(lines[2+s]); int child=int(Float.parseFloat(parse[7])); strain[s].childID=child; if(child!=-1) { strain[s].child=strain[child]; strain[s].child.parent=strain[s]; } } } genome(genome g,creature p) { parent=p; strainLength=g.strainLength; strain=new gene[strainLength]; // System.arraycopy(g.strain,0,strain,0,strain.length); for(int i=0;i<strain.length;i++) { strain[i]=new gene(g.strain[i]); } strainKey=g.strainKey; } genome(int sl,creature p) { strainKey=""; parent=p; strainLength=sl; strain=new gene[strainLength]; for(int i=0;i<strainLength;i++) { //INITIAL CONDITIONS FOR RANDOM GENES float rkey=random(4); int repeat=int(random(parent.maxRepeat)); float neuronWeight; if(random(100)>50) neuronWeight=1; else neuronWeight=-1; float neuronPower=random(0,2); boolean bidirectional=false; if(random(100)>50) bidirectional=true; float heading=random(-360,360); float distance=random(p.minDistance,p.cohesionDistance); strain[i]=new gene(i,repeat,int(heading),distance,neuronWeight,neuronPower,bidirectional,int(rkey)); if(random(100)>30&&!strain[i].isLightSensor) { strain[i].isNeuron=false; } } int maxConnections=int(strainLength*.8); for(int s=0;s<maxConnections;s++) { int r=int(random(strainLength)); do { r=int(random(strainLength)); boolean repeat=true; gene temp; temp=new gene(strain[s]); temp.child=strain[r]; do { if(temp.child.child==null) { repeat=false; } else { if(temp.child.child.id==s) { r=s; break; } temp.child=temp.child.child; } } while(repeat); } while(r==s); strain[s].child=strain[r]; strain[s].childID=r; strain[s].child.parent=strain[s]; } } void buildKey() { strainKey=""; strainKey+="name @ "; float pa=parent.amount; float pcd=parent.cohesionDistance; float pmd=parent.minDistance; float pcl=parent.collisionDistance; strainKey+=pa+" "+pcd+" "+pmd+" "+pcl+" @ "; for(int i=0;i<strain.length;i++) { int ci=strain[i].childID; int r=strain[i].repeat; float h=strain[i].heading; int rkey=strain[i].rkey; float nw=strain[i].neuronWeight; float d=strain[i].distance; float np=strain[i].neuronPower; int bd=int(strain[i].bidirectional); strainKey+=r+" "+h+" "+d+" "+nw+" "+np+" "+bd+" "+rkey+" "+ci+" @ "; // strain[i]=new gene(i,repeat,int(heading),distance,neuronWeight,neuronPower,bidirectional,int(rkey)); } // println("Current Creature: "+strainKey); } gene returnChild(int id) { if(id>0&&id<strainLength) { return strain[id]; } else return null; } void mutateAngle(gene g) { g.heading+=random(-6,6); // g.heading=random(360); } void mutateDistance(gene g) { g.distance+=random(-.1,.1); if(g.distance<parent.minDistance) g.distance=parent.minDistance; if(g.distance>parent.cohesionDistance); g.distance=parent.cohesionDistance-.1; } void mutateRepeat(gene g) { g.repeat=int(random(parent.maxRepeat)); } void mutateKey(gene g) { g.rkey=int(random(4)); } void mutateNeurons(gene g) { int rm=int(random(4)); switch(rm) { case 0: if(random(100)>50) g.neuronWeight=1; else g.neuronWeight=-1; break; case 1: if(random(100)>50) g.bidirectional=false; else g.bidirectional=true; break; case 2: g.neuronPower=random(0,2); break; } } void mutateChild(gene g) { if(random(100)>50&&g!=strain[0]) { g.child=null; g.childID=-1; } else { int rc=int(random(strainLength)); if(strain[rc].child==null) { g.child=strain[rc]; g.childID=rc; } } } void deleteChild(gene g) { if(g.child==null||g==strain[0]) return; else { } } void addGene() { strainLength++; gene temp[]=new gene[strainLength]; System.arraycopy(strain,0,temp,0,strain.length); float rkey=random(4); int repeat=int(random(parent.maxRepeat)); float neuronWeight; if(random(100)>50) neuronWeight=1; else neuronWeight=-1; float neuronPower=random(0,2); boolean bidirectional=false; if(random(100)>50) bidirectional=true; float heading=random(-360,360); float distance=random(parent.minDistance,parent.cohesionDistance); temp[strainLength-1]=new gene(strainLength-1,repeat,int(heading),distance,neuronWeight,neuronPower,bidirectional,int(rkey)); if(random(100)>30&&!temp[strainLength-1].isLightSensor) { temp[strainLength-1].isNeuron=false; } strain=temp; } void garbageCollect() { // for } void mutateMorph() { int rg=int(random(strainLength)); while(strain[rg].usedInPhenotype==false) { rg=int(random(strainLength)); } gene cg=strain[rg]; int rm=int(random(5)); switch(rm) { case 0: mutateAngle(cg); break; case 1: mutateDistance(cg); break; case 2: mutateRepeat(cg); break; case 3: mutateKey(cg); break; case 4: for(int m=0;m<5;m++) mutateChild(cg); break; } // if(random(100)>60) // addGene(); // buildKey(); } void mutateNS() { int rg=int(random(strainLength)); gene cg=strain[rg]; while(strain[rg].usedInPhenotype==false&&strain[rg].isNeuron==false) { rg=int(random(strainLength)); cg=strain[rg]; } mutateNeurons(cg); } void clearTags() { for(int r=0;r<strain.length;r++) { strain[r].usedInPhenotype=false; } } }