Changeset 671
- Timestamp:
- 08/18/17 15:24:59 (7 years ago)
- Location:
- cpp/frams/genetics
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/f1/conv_f1.cpp
r534 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 10 10 #include <ctype.h> 11 11 12 //#define v1f1COMPATIBLE 13 14 F1Props stdprops ={1, 0, 1, 0.4, 0.25, 0.25, 0.25, 0.25, 0.0, 1.0, 1.0, 1,15 0.2, 0.5,0.5,0.5 };12 //#define v1f1COMPATIBLE //as in ancient Framsticks 1.x 13 14 F1Props stdprops = { 1, 0, 1, 0.4, 0.25, 0.25, 0.25, 0.25, 0.0, 1.0, 1.0, 1, 15 0.2, 0.5, 0.5, 0.5 }; 16 16 17 17 class Builder 18 18 { 19 19 public: 20 Builder(const char*g,int mapping=0):invalid(0),genbegin(g),usemapping(mapping),first_part_mapping(NULL),energ(0),energ_div(0) {} 21 ~Builder() {SAFEDELETE(first_part_mapping);} 22 char tmp[222]; 23 bool invalid; 24 Model model; 25 const char *genbegin; 26 SList neuro_f1_to_f0; // neuro_f1_to_f0(f1_refno) = actual neuro pointer 27 Neuro *last_f1_neuro; 28 SyntParam *neuro_cls_param; 29 30 struct Connection { int n1,n2; double w; 31 Connection(int _n1,int _n2, double _w):n1(_n1),n2(_n2),w(_w) {} }; 32 33 SListTempl<Connection> connections; 34 int usemapping; 35 MultiRange range; 36 MultiRange *first_part_mapping; 37 double lastjoint_muscle_power; 38 double energ,energ_div; 39 void grow(int part1,const char*g,Pt3D k,F1Props c); 40 void setPartMapping(int p,const char* g); 41 int growJoint(int part1,int part2,Pt3D &angle,F1Props &c,const char *g); 42 int growPart(F1Props &c,const char *g); 43 const char *skipNeuro(const char *z); 44 const char* growNeuro(const char* t,F1Props &c,int&); 45 void growConnection(const char* begin,const char* colon,const char* end,F1Props& props); 46 int countBranches(const char*g,SList &out); 47 SyntParam* lastNeuroClassParam(); 48 void addClassParam(const char* name,double value); 49 void addClassParam(const char* name,const char* value); 50 51 const MultiRange* makeRange(const char*g) {return makeRange(g,g);} 52 const MultiRange* makeRange(const char*g,const char*g2); 53 Part *getLastPart() {return getLastJoint()->part2;} 54 Neuro *getLastNeuro() {return model.getNeuro(model.getNeuroCount()-1);} 55 Joint *getLastJoint() {return model.getJoint(model.getJointCount()-1);} 56 void addOrRememberInput(int n1,int n2,double w) 57 { 20 Builder(const char*g, int mapping = 0) :invalid(0), genbegin(g), usemapping(mapping), first_part_mapping(NULL), model_energy(0), model_energy_max(0) {} 21 ~Builder() { SAFEDELETE(first_part_mapping); } 22 char tmp[222]; 23 bool invalid; 24 Model model; 25 const char *genbegin; 26 SList neuro_f1_to_f0; // neuro_f1_to_f0(f1_refno) = actual neuro pointer 27 Neuro *last_f1_neuro; 28 SyntParam *neuro_cls_param; 29 30 struct Connection 31 { 32 int n1, n2; double w; 33 Connection(int _n1, int _n2, double _w) :n1(_n1), n2(_n2), w(_w) {} 34 }; 35 36 SListTempl<Connection> connections; 37 int usemapping; 38 MultiRange range; 39 MultiRange *first_part_mapping; 40 double lastjoint_muscle_power; 41 double model_energy, model_energy_max; 42 void grow(int part1, const char*g, Pt3D k, F1Props c); 43 void setPartMapping(int p, const char* g); 44 int growJoint(int part1, int part2, Pt3D &angle, F1Props &c, const char *g); 45 int growPart(F1Props &c, const char *g); 46 const char *skipNeuro(const char *z); 47 const char* growNeuro(const char* t, F1Props &c, int&); 48 void growConnection(const char* begin, const char* colon, const char* end, F1Props& props); 49 int countBranches(const char*g, SList &out); 50 SyntParam* lastNeuroClassParam(); 51 void addClassParam(const char* name, double value); 52 void addClassParam(const char* name, const char* value); 53 54 const MultiRange* makeRange(const char*g) { return makeRange(g, g); } 55 const MultiRange* makeRange(const char*g, const char*g2); 56 Part *getLastPart() { return getLastJoint()->part2; } 57 Neuro *getLastNeuro() { return model.getNeuro(model.getNeuroCount() - 1); } 58 Joint *getLastJoint() { return model.getJoint(model.getJointCount() - 1); } 59 void addOrRememberInput(int n1, int n2, double w) 60 { 58 61 //if (!addInput(n1,n2,w,false)) 59 connections +=Connection(n1,n2,w);60 61 bool addInput(int n1,int n2,double w,bool final)62 63 if ((n1 <0) || (n2<0) || (n1>=neuro_f1_to_f0.size()) || (n2>=neuro_f1_to_f0.size()))64 65 if (final) logPrintf("GenoConvF1", "addInput",LOG_WARN,66 "illegal neuron connection %d <- %d (ignored)",n1,n2);62 connections += Connection(n1, n2, w); 63 } 64 bool addInput(int n1, int n2, double w, bool final) 65 { 66 if ((n1 < 0) || (n2 < 0) || (n1 >= neuro_f1_to_f0.size()) || (n2 >= neuro_f1_to_f0.size())) 67 { 68 if (final) logPrintf("GenoConvF1", "addInput", LOG_WARN, 69 "illegal neuron connection %d <- %d (ignored)", n1, n2); 67 70 return 0; 68 69 Neuro *neuro =(Neuro*)neuro_f1_to_f0(n1);70 Neuro *input =(Neuro*)neuro_f1_to_f0(n2);71 neuro->addInput(input, w);71 } 72 Neuro *neuro = (Neuro*)neuro_f1_to_f0(n1); 73 Neuro *input = (Neuro*)neuro_f1_to_f0(n2); 74 neuro->addInput(input, w); 72 75 return 1; 73 74 void addPendingInputs()75 76 for (int i=0;i<connections.size();i++)77 78 Connection *c =&connections(i);79 addInput(c->n1, c->n2,c->w,true);80 81 76 } 77 void addPendingInputs() 78 { 79 for (int i = 0; i < connections.size(); i++) 80 { 81 Connection *c = &connections(i); 82 addInput(c->n1, c->n2, c->w, true); 83 } 84 } 82 85 }; 83 86 84 const MultiRange* Builder::makeRange(const char*g, const char*g2)85 { 86 if (!usemapping) return 0;87 range.clear();88 range.add(g-genbegin,g2-genbegin);89 return ⦥90 } 91 92 void F1Props:: wykluczanie()93 { 94 double s=ruch+asym+odpor+wchl;95 ruch=ruch/s;96 asym=asym/s;97 odpor=odpor/s;98 wchl=wchl/s;87 const MultiRange* Builder::makeRange(const char*g, const char*g2) 88 { 89 if (!usemapping) return 0; 90 range.clear(); 91 range.add(g - genbegin, g2 - genbegin); 92 return ⦥ 93 } 94 95 void F1Props::normalizeBiol4() 96 { 97 double sum = muscle_power + assimilation + stamina + ingestion; 98 muscle_power /= sum; 99 assimilation /= sum; 100 stamina /= sum; 101 ingestion /= sum; 99 102 } 100 103 101 104 /** main conversion function - with conversion map support */ 102 SString GenoConv_f1::convert(SString &i, MultiMap *map)103 { 104 const char* g=i.c_str();105 Builder builder(g,map?1:0);106 builder.model.open();107 builder.grow(-1,g,Pt3D_0,stdprops); // uses Model::singleStepBuild to create model elements108 if (builder.invalid) return SString();109 builder.addPendingInputs();110 builder.model.startenergy=(builder.energ_div>0)?(builder.energ/builder.energ_div):1.0;111 builder.model.close(); // model is ready to use now112 if (map) builder.model.getCurrentToF0Map(*map); // generate f1-to-f0 conversion map113 return builder.model.getF0Geno().getGenes();114 } 115 116 void Builder::setPartMapping(int p, const char* g)117 { 118 if (!usemapping) return;119 const MultiRange *r=makeRange(g);120 if (p<0)105 SString GenoConv_f1::convert(SString &i, MultiMap *map) 106 { 107 const char* g = i.c_str(); 108 Builder builder(g, map ? 1 : 0); 109 builder.model.open(); 110 builder.grow(-1, g, Pt3D_0, stdprops); // uses Model::singleStepBuild to create model elements 111 if (builder.invalid) return SString(); 112 builder.addPendingInputs(); 113 builder.model.startenergy = (builder.model_energy_max > 0) ? (builder.model_energy / builder.model_energy_max) : 1.0; 114 builder.model.close(); // model is ready to use now 115 if (map) builder.model.getCurrentToF0Map(*map); // generate f1-to-f0 conversion map 116 return builder.model.getF0Geno().getGenes(); 117 } 118 119 void Builder::setPartMapping(int p, const char* g) 120 { 121 if (!usemapping) return; 122 const MultiRange *r = makeRange(g); 123 if (p < 0) 121 124 { //special case: mapping the part which is not yet created 122 if (first_part_mapping) first_part_mapping->add(*r);123 else first_part_mapping=new MultiRange(*r);124 } 125 else126 model.getPart(p)->addMapping(*r);127 } 128 129 void Builder::grow(int part1, const char*g,Pt3D k,F1Props c)130 { 131 int hasmuscles=0;132 k+=Pt3D(c.rot,0,c.skr);133 while(1)134 {135 switch(*g)136 {137 case 0: case ',': case ')': return;138 case 'R': k.x+=0.7853; setPartMapping(part1,g); break;139 case 'r': k.x-=0.7853; setPartMapping(part1,g); break;140 case 'Q': c.rot+=(1.58-c.rot)*0.3; setPartMapping(part1,g); break;141 case 'q': c.rot+=(-1.58-c.rot)*0.3; setPartMapping(part1,g); break;125 if (first_part_mapping) first_part_mapping->add(*r); 126 else first_part_mapping = new MultiRange(*r); 127 } 128 else 129 model.getPart(p)->addMapping(*r); 130 } 131 132 void Builder::grow(int part1, const char*g, Pt3D k, F1Props c) 133 { 134 int hasmuscles = 0; 135 k += Pt3D(c.twist, 0, c.curvedness); 136 while (1) 137 { 138 switch (*g) 139 { 140 case 0: case ',': case ')': return; 141 case 'R': k.x += 0.7853; setPartMapping(part1, g); break; 142 case 'r': k.x -= 0.7853; setPartMapping(part1, g); break; 143 case 'Q': c.twist += (1.58 - c.twist)*0.3; setPartMapping(part1, g); break; 144 case 'q': c.twist += (-1.58 - c.twist)*0.3; setPartMapping(part1, g); break; 142 145 #ifdef v1f1COMPATIBLE 143 case 'L': c.dlug+=(3.0-c.dlug)*0.3; setPartMapping(part1,g); break;146 case 'L': c.length += (3.0 - c.length)*0.3; setPartMapping(part1, g); break; 144 147 #else 145 case 'L': c.dlug+=(2.0-c.dlug)*0.3; setPartMapping(part1,g); break;148 case 'L': c.length += (2.0 - c.length)*0.3; setPartMapping(part1, g); break; 146 149 #endif 147 case 'l': c.dlug+=(0.33-c.dlug)*0.3; setPartMapping(part1,g); break;148 case 'A': c.asym+=(1-c.asym)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;149 case 'a': c.asym-=c.asym*0.4; c.wykluczanie(); setPartMapping(part1,g); break;150 case 'I': c.wchl+=(1-c.wchl)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;151 case 'i': c.wchl-=c.wchl*0.4; c.wykluczanie(); setPartMapping(part1,g); break;152 case 'S': c.odpor+=(1-c.odpor)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;153 case 's': c.odpor-=c.odpor*0.4; c.wykluczanie(); setPartMapping(part1,g); break;154 case 'M': c.ruch+=(1-c.ruch)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;155 case 'm': c.ruch-=c.ruch*0.4; c.wykluczanie(); setPartMapping(part1,g); break;156 case 'C': c.skr+=(2.0-c.skr)*0.25; setPartMapping(part1,g); break;157 case 'c': c.skr+=(-2.0-c.skr)*0.25; setPartMapping(part1,g); break;158 case 'F': c.tarcie+=(4-c.tarcie)*0.2; setPartMapping(part1,g); break;159 case 'f': c.tarcie-=c.tarcie*0.2; setPartMapping(part1,g); break;160 case 'W': c.masa+=(2.0-c.masa)*0.3; setPartMapping(part1,g); break;161 case 'w': c.masa+=(0.5-c.masa)*0.3; setPartMapping(part1,g); break;162 case 'E': c.energ+=(10.0-c.energ)*0.1; setPartMapping(part1,g); break;163 case 'e': c.energ-=c.energ*0.1; setPartMapping(part1,g); break;164 165 case 'D': c.cred+=(1.0-c.cred)*0.25; setPartMapping(part1,g); break;166 case 'd': c.cred+=(0.0-c.cred)*0.25; setPartMapping(part1,g); break;167 case 'G': c.cgreen+=(1.0-c.cgreen)*0.25; setPartMapping(part1,g); break;168 case 'g': c.cgreen+=(0.0-c.cgreen)*0.25; setPartMapping(part1,g); break;169 case 'B': c.cblue+=(1.0-c.cblue)*0.25; setPartMapping(part1,g); break;170 case 'b': c.cblue+=(0.0-c.cblue)*0.25; setPartMapping(part1,g); break;171 case 'H': c.grub+=(0.7-c.grub)*0.25; setPartMapping(part1,g); break;172 case 'h': c.grub+=(0.05-c.grub)*0.25; setPartMapping(part1,g); break;173 174 case '[': //neuron175 // setdebug(g-(char*)geny,DEBUGNEURO | !l_neu);176 if (model.getJointCount())177 g=growNeuro(g+1,c,hasmuscles);178 else179 { 180 logMessage("GenoConv_F1","grow",1,"Illegal neuron position (ignored)");181 g=skipNeuro(g+1);182 } 183 break;184 case 'X':185 { 186 int freshpart=0;187 //setdebug(g-(char*)geny,DEBUGEST | !l_est);188 if (part1<0) //initial grow189 { 190 if (model.getPartCount()>0)191 part1=0;192 193 194 part1=growPart(c,g);195 freshpart=1;196 197 198 199 200 if (!freshpart)201 { 202 Part *part=model.getPart(part1);203 part->density=((part->mass*part->density)+1.0/c.masa)/(part->mass+1.0); // v=m*d204 // part->volume+=1.0/c.masa;205 part->mass+=1.0;206 } 207 energ+=0.9*c.energ+0.1;208 energ_div+=1.0;209 210 int part2 = growPart(c,g);211 growJoint(part1,part2,k,c,g);212 // est* e = new est(*s,*s2,k,c,zz,this);213 214 // oslabianie cech wzdluz struktury215 c.dlug=0.5*c.dlug+0.5*stdprops.dlug;216 c.grub=0.5*c.grub+0.5*stdprops.grub;217 c.skr=0.66*c.skr;218 c.rot=0.66*c.rot;219 c.tarcie=0.8*c.tarcie+0.2*stdprops.tarcie;220 221 c.asym=0.8*c.asym+0.2*stdprops.asym;222 c.odpor=0.8*c.odpor+0.2*stdprops.odpor;223 c.ruch=0.8*c.ruch+0.2*stdprops.ruch;224 c.wchl=0.8*c.wchl+0.2*stdprops.wchl;225 c.masa+=(stdprops.masa-c.masa)*0.5;226 c.wykluczanie();227 228 if (c.resetrange) c.bendrange=1.0; else c.resetrange=1;229 grow(part2,g+1,Pt3D_0,c);230 return;231 } 232 case '(':233 { 234 setPartMapping(part1,g);235 SList ga;236 int i,ile;237 ile=countBranches(g+1,ga);238 c.resetrange=0;239 c.bendrange=1.0/ile;240 for (i=0;i<ile;i++)241 grow(part1,(char*)ga(i),k+Pt3D(0,0,-3.141+(i+1)*(6.282/(ile+1))),c);242 return;243 } 244 case ' ': case '\t': case '\n': case '\r': break;245 default: invalid=1; return;246 }247 g++;150 case 'l': c.length += (0.33 - c.length)*0.3; setPartMapping(part1, g); break; 151 case 'A': c.assimilation += (1 - c.assimilation)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 152 case 'a': c.assimilation -= c.assimilation*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 153 case 'I': c.ingestion += (1 - c.ingestion)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 154 case 'i': c.ingestion -= c.ingestion*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 155 case 'S': c.stamina += (1 - c.stamina)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 156 case 's': c.stamina -= c.stamina*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 157 case 'M': c.muscle_power += (1 - c.muscle_power)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 158 case 'm': c.muscle_power -= c.muscle_power*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 159 case 'C': c.curvedness += (2.0 - c.curvedness)*0.25; setPartMapping(part1, g); break; 160 case 'c': c.curvedness += (-2.0 - c.curvedness)*0.25; setPartMapping(part1, g); break; 161 case 'F': c.friction += (4 - c.friction)*0.2; setPartMapping(part1, g); break; 162 case 'f': c.friction -= c.friction*0.2; setPartMapping(part1, g); break; 163 case 'W': c.weight += (2.0 - c.weight)*0.3; setPartMapping(part1, g); break; 164 case 'w': c.weight += (0.5 - c.weight)*0.3; setPartMapping(part1, g); break; 165 case 'E': c.energy += (10.0 - c.energy)*0.1; setPartMapping(part1, g); break; 166 case 'e': c.energy -= c.energy*0.1; setPartMapping(part1, g); break; 167 168 case 'D': c.cred += (1.0 - c.cred)*0.25; setPartMapping(part1, g); break; 169 case 'd': c.cred += (0.0 - c.cred)*0.25; setPartMapping(part1, g); break; 170 case 'G': c.cgreen += (1.0 - c.cgreen)*0.25; setPartMapping(part1, g); break; 171 case 'g': c.cgreen += (0.0 - c.cgreen)*0.25; setPartMapping(part1, g); break; 172 case 'B': c.cblue += (1.0 - c.cblue)*0.25; setPartMapping(part1, g); break; 173 case 'b': c.cblue += (0.0 - c.cblue)*0.25; setPartMapping(part1, g); break; 174 case 'H': c.visual_size += (0.7 - c.visual_size)*0.25; setPartMapping(part1, g); break; 175 case 'h': c.visual_size += (0.05 - c.visual_size)*0.25; setPartMapping(part1, g); break; 176 177 case '[': //neuron 178 // setdebug(g-(char*)geny,DEBUGNEURO | !l_neu); 179 if (model.getJointCount()) 180 g = growNeuro(g + 1, c, hasmuscles); 181 else 182 { 183 logMessage("GenoConv_F1", "grow", 1, "Illegal neuron position (ignored)"); 184 g = skipNeuro(g + 1); 185 } 186 break; 187 case 'X': 188 { 189 int freshpart = 0; 190 //setdebug(g-(char*)geny,DEBUGEST | !l_est); 191 if (part1 < 0) //initial grow 192 { 193 if (model.getPartCount() > 0) 194 part1 = 0; 195 else 196 { 197 part1 = growPart(c, g); 198 freshpart = 1; 199 if (first_part_mapping) 200 model.getPart(part1)->setMapping(*first_part_mapping); 201 } 202 } 203 if (!freshpart) 204 { 205 Part *part = model.getPart(part1); 206 part->density = ((part->mass*part->density) + 1.0 / c.weight) / (part->mass + 1.0); // v=m*d 207 // part->volume+=1.0/c.weight; 208 part->mass += 1.0; 209 } 210 model_energy += 0.9*c.energy + 0.1; 211 model_energy_max += 1.0; 212 213 int part2 = growPart(c, g); 214 growJoint(part1, part2, k, c, g); 215 // est* e = new est(*s,*s2,k,c,zz,this); 216 217 // attenuate properties as they are propagated along the structure 218 c.length = 0.5*c.length + 0.5*stdprops.length; 219 c.visual_size = 0.5*c.visual_size + 0.5*stdprops.visual_size; 220 c.curvedness = 0.66*c.curvedness; 221 c.twist = 0.66*c.twist; 222 c.friction = 0.8*c.friction + 0.2*stdprops.friction; 223 224 c.assimilation = 0.8*c.assimilation + 0.2*stdprops.assimilation; 225 c.stamina = 0.8*c.stamina + 0.2*stdprops.stamina; 226 c.muscle_power = 0.8*c.muscle_power + 0.2*stdprops.muscle_power; 227 c.ingestion = 0.8*c.ingestion + 0.2*stdprops.ingestion; 228 c.weight += (stdprops.weight - c.weight)*0.5; 229 c.normalizeBiol4(); 230 231 if (c.muscle_reset_range) c.muscle_bend_range = 1.0; else c.muscle_reset_range = true; 232 grow(part2, g + 1, Pt3D_0, c); 233 return; 234 } 235 case '(': 236 { 237 setPartMapping(part1, g); 238 SList ga; 239 int i, count; 240 count = countBranches(g + 1, ga); 241 c.muscle_reset_range = false; 242 c.muscle_bend_range = 1.0 / count; 243 for (i = 0; i < count; i++) 244 grow(part1, (char*)ga(i), k + Pt3D(0, 0, -M_PI + (i + 1)*(2*M_PI / (count + 1))), c); 245 return; 246 } 247 case ' ': case '\t': case '\n': case '\r': break; 248 default: invalid = 1; return; 249 } 250 g++; 248 251 } 249 252 } … … 251 254 SyntParam* Builder::lastNeuroClassParam() 252 255 { 253 if (!neuro_cls_param)254 { 255 NeuroClass *cls=last_f1_neuro->getClass();256 if (cls)257 { 258 neuro_cls_param=new SyntParam(last_f1_neuro->classProperties());259 // this is equivalent to:260 // SyntParam tmp=last_f1_neuro->classProperties();261 // neuro_cls_param=new SyntParam(tmp);262 // interestingly, some compilers eliminate the call to new SyntParam,263 // realizing that a copy constructor is redundant when the original object is264 // temporary. there are no side effect of such optimization, as long as the265 // copy-constructed object is exact equivalent of the original.266 } 267 } 268 return neuro_cls_param;269 } 270 271 void Builder::addClassParam(const char* name, double value)272 { 273 lastNeuroClassParam();274 if (neuro_cls_param)275 neuro_cls_param->setDoubleById(name,value);276 } 277 278 void Builder::addClassParam(const char* name, const char* value)279 { 280 lastNeuroClassParam();281 if (neuro_cls_param)282 { 283 ExtValue e(value);284 const ExtValue &re(e);285 neuro_cls_param->setById(name,re);286 } 287 } 288 289 int Builder::countBranches(const char*g, SList &out)290 { 291 int gl=0;292 out+=(void*)g;293 while (gl>=0)294 { 295 switch(*g)296 { 297 case 0: gl =-1; break;256 if (!neuro_cls_param) 257 { 258 NeuroClass *cls = last_f1_neuro->getClass(); 259 if (cls) 260 { 261 neuro_cls_param = new SyntParam(last_f1_neuro->classProperties()); 262 // this is equivalent to: 263 // SyntParam tmp=last_f1_neuro->classProperties(); 264 // neuro_cls_param=new SyntParam(tmp); 265 // interestingly, some compilers eliminate the call to new SyntParam, 266 // realizing that a copy constructor is redundant when the original object is 267 // temporary. there are no side effect of such optimization, as long as the 268 // copy-constructed object is exact equivalent of the original. 269 } 270 } 271 return neuro_cls_param; 272 } 273 274 void Builder::addClassParam(const char* name, double value) 275 { 276 lastNeuroClassParam(); 277 if (neuro_cls_param) 278 neuro_cls_param->setDoubleById(name, value); 279 } 280 281 void Builder::addClassParam(const char* name, const char* value) 282 { 283 lastNeuroClassParam(); 284 if (neuro_cls_param) 285 { 286 ExtValue e(value); 287 const ExtValue &re(e); 288 neuro_cls_param->setById(name, re); 289 } 290 } 291 292 int Builder::countBranches(const char*g, SList &out) 293 { 294 int gl = 0; 295 out += (void*)g; 296 while (gl >= 0) 297 { 298 switch (*g) 299 { 300 case 0: gl = -1; break; 298 301 case '(': case '[': ++gl; break; 299 302 case ')': case ']': --gl; break; 300 case ',': if (!gl) out +=(void*)(g+1);301 } 302 g++;303 } 304 return out.size();305 } 306 307 int Builder::growJoint(int part1, int part2,Pt3D &angle,F1Props &c,const char *g)308 { 309 double len=min(2.0,c.dlug);310 sprintf(tmp,"j:p1=%ld,p2=%ld,dx=%lg,rx=%lg,ry=%lg,rz=%lg,stam=%lg,vr=%g,vg=%g,vb=%g",311 part1,part2,len,angle.x,angle.y,angle.z,c.odpor, c.cred,c.cgreen,c.cblue);312 lastjoint_muscle_power=c.ruch;313 return model.singleStepBuild(tmp,makeRange(g));314 } 315 316 int Builder::growPart(F1Props &c, const char *g)317 { 318 sprintf(tmp,"p:dn=%lg,fr=%lg,ing=%lg,as=%lg,vs=%g,vr=%g,vg=%g,vb=%g",319 1.0/c.masa,c.tarcie,c.wchl,c.asym, c.grub, c.cred,c.cgreen,c.cblue);320 return model.singleStepBuild(tmp,makeRange(g));303 case ',': if (!gl) out += (void*)(g + 1); 304 } 305 g++; 306 } 307 return out.size(); 308 } 309 310 int Builder::growJoint(int part1, int part2, Pt3D &angle, F1Props &c, const char *g) 311 { 312 double len = min(2.0, c.length); 313 sprintf(tmp, "j:p1=%ld,p2=%ld,dx=%lg,rx=%lg,ry=%lg,rz=%lg,stam=%lg,vr=%g,vg=%g,vb=%g", 314 part1, part2, len, angle.x, angle.y, angle.z, c.stamina, c.cred, c.cgreen, c.cblue); 315 lastjoint_muscle_power = c.muscle_power; 316 return model.singleStepBuild(tmp, makeRange(g)); 317 } 318 319 int Builder::growPart(F1Props &c, const char *g) 320 { 321 sprintf(tmp, "p:dn=%lg,fr=%lg,ing=%lg,as=%lg,vs=%g,vr=%g,vg=%g,vb=%g", 322 1.0 / c.weight, c.friction, c.ingestion, c.assimilation, c.visual_size, c.cred, c.cgreen, c.cblue); 323 return model.singleStepBuild(tmp, makeRange(g)); 321 324 } 322 325 323 326 const char *Builder::skipNeuro(const char *z) 324 327 { 325 for (;*z;z++) if ((*z==']')||(*z==')')) break;326 return z-1;327 } 328 329 const char* Builder::growNeuro(const char* t, F1Props& props, int &hasmuscles)330 { 331 const char*neuroend=skipNeuro(t);332 last_f1_neuro=model.addNewNeuro();333 neuro_cls_param=NULL;334 last_f1_neuro->attachToPart(getLastPart());335 const MultiRange *mr=makeRange(t-1,neuroend+1);336 if (mr) last_f1_neuro->addMapping(*mr);337 neuro_f1_to_f0+=last_f1_neuro;338 339 SString clsname;340 bool haveclass=0;341 while(*t && *t<=' ') t++;342 const char* next=(*t)?(t+1):t;343 while(*next && *next<=' ') next++;344 if (*t && *next!=',' && *next!=']') // old style muscles [|rest] or [@rest]345 switch(*t)346 { 347 case '@': if (t[1]==':') break;348 haveclass=1;349 // if (!(hasmuscles&1))350 351 hasmuscles|=1;352 Neuro *muscle=model.addNewNeuro();353 sprintf(tmp,"@:p=%lg",lastjoint_muscle_power);354 355 356 357 358 359 t++;360 break;361 case '|': if (t[1]==':') break;362 haveclass=1;363 // if (!(hasmuscles&2))364 365 hasmuscles|=2;366 Neuro *muscle=model.addNewNeuro();367 sprintf(tmp,"|:p=%lg,r=%lg",lastjoint_muscle_power,props.bendrange);368 369 370 371 372 373 t++;374 break;375 } 376 while(*t && *t<=' ') t++;377 bool finished=0;378 const char *begin=t;379 const char* colon=0;380 SString classparams;381 while(!finished)382 { 383 switch (*t)384 { 385 case ':': colon =t; break;386 case 0: case ']': case ')': finished =1;328 for (; *z; z++) if ((*z == ']') || (*z == ')')) break; 329 return z - 1; 330 } 331 332 const char* Builder::growNeuro(const char* t, F1Props& props, int &hasmuscles) 333 { 334 const char*neuroend = skipNeuro(t); 335 last_f1_neuro = model.addNewNeuro(); 336 neuro_cls_param = NULL; 337 last_f1_neuro->attachToPart(getLastPart()); 338 const MultiRange *mr = makeRange(t - 1, neuroend + 1); 339 if (mr) last_f1_neuro->addMapping(*mr); 340 neuro_f1_to_f0 += last_f1_neuro; 341 342 SString clsname; 343 bool haveclass = 0; 344 while (*t && *t <= ' ') t++; 345 const char* next = (*t) ? (t + 1) : t; 346 while (*next && *next <= ' ') next++; 347 if (*t && *next != ',' && *next != ']') // old style muscles [|rest] or [@rest] 348 switch (*t) 349 { 350 case '@': if (t[1] == ':') break; 351 haveclass = 1; 352 // if (!(hasmuscles&1)) 353 { 354 hasmuscles |= 1; 355 Neuro *muscle = model.addNewNeuro(); 356 sprintf(tmp, "@:p=%lg", lastjoint_muscle_power); 357 muscle->addInput(last_f1_neuro); 358 muscle->setDetails(tmp); 359 muscle->attachToJoint(getLastJoint()); 360 if (usemapping) muscle->addMapping(*makeRange(t)); 361 } 362 t++; 363 break; 364 case '|': if (t[1] == ':') break; 365 haveclass = 1; 366 // if (!(hasmuscles&2)) 367 { 368 hasmuscles |= 2; 369 Neuro *muscle = model.addNewNeuro(); 370 sprintf(tmp, "|:p=%lg,r=%lg", lastjoint_muscle_power, props.muscle_bend_range); 371 muscle->addInput(last_f1_neuro); 372 muscle->setDetails(tmp); 373 muscle->attachToJoint(getLastJoint()); 374 if (usemapping) muscle->addMapping(*makeRange(t)); 375 } 376 t++; 377 break; 378 } 379 while (*t && *t <= ' ') t++; 380 bool finished = 0; 381 const char *begin = t; 382 const char* colon = 0; 383 SString classparams; 384 while (!finished) 385 { 386 switch (*t) 387 { 388 case ':': colon = t; break; 389 case 0: case ']': case ')': finished = 1; 387 390 // NO break! 388 391 case ',': 389 if ( !haveclass && !colon && t>begin ) 392 if (!haveclass && !colon && t > begin) 393 { 394 haveclass = 1; 395 SString clsname(begin, t - begin); 396 clsname = trim(clsname); 397 last_f1_neuro->setClassName(clsname); 398 NeuroClass *cls = last_f1_neuro->getClass(); 399 if (cls) 390 400 { 391 haveclass=1; 392 SString clsname(begin,t-begin); 393 clsname=trim(clsname); 394 last_f1_neuro->setClassName(clsname); 395 NeuroClass *cls=last_f1_neuro->getClass(); 396 if (cls) 397 { 398 if (cls->getPreferredLocation()==2) 401 if (cls->getPreferredLocation() == 2) 399 402 last_f1_neuro->attachToJoint(getLastJoint()); 400 else if (cls->getPreferredLocation() ==1)403 else if (cls->getPreferredLocation() == 1) 401 404 last_f1_neuro->attachToPart(getLastPart()); 402 405 403 406 lastNeuroClassParam(); 404 407 //special handling: muscle properties (can be overwritten by subsequent property assignments) 405 if (!strcmp(cls->getName().c_str(),"|")) 406 { 407 neuro_cls_param->setDoubleById("p",lastjoint_muscle_power); 408 neuro_cls_param->setDoubleById("r",props.bendrange); 409 } 410 else if (!strcmp(cls->getName().c_str(),"@")) 411 { 412 neuro_cls_param->setDoubleById("p",lastjoint_muscle_power); 413 } 408 if (!strcmp(cls->getName().c_str(), "|")) 409 { 410 neuro_cls_param->setDoubleById("p", lastjoint_muscle_power); 411 neuro_cls_param->setDoubleById("r", props.muscle_bend_range); 412 } 413 else if (!strcmp(cls->getName().c_str(), "@")) 414 { 415 neuro_cls_param->setDoubleById("p", lastjoint_muscle_power); 414 416 } 415 417 } 416 else if (colon && (colon>begin) && (t>colon)) 417 growConnection(begin,colon,t,props); 418 if (t[0]!=',') t--; 419 begin=t+1; colon=0; 418 } 419 else if (colon && (colon > begin) && (t > colon)) 420 growConnection(begin, colon, t, props); 421 if (t[0] != ',') t--; 422 begin = t + 1; colon = 0; 420 423 break; 421 424 } 422 t++;423 } 424 SAFEDELETE(neuro_cls_param);425 return t;426 } 427 void Builder::growConnection(const char* begin, const char* colon, const char* end,F1Props& props)428 { 429 while(*begin && *begin<=' ') begin++;430 int i;431 if (isdigit(begin[0]) || (begin[0]=='-'))432 { 433 double weight=ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str());434 paInt relative=ExtValue::getInt(trim(SString(begin,colon-begin)).c_str(),false);435 int this_refno=neuro_f1_to_f0.size()-1;436 addOrRememberInput(this_refno,this_refno+relative,weight);437 } 438 else if ((i=last_f1_neuro->extraProperties().findIdn(begin,colon-begin))>=0)439 { 440 last_f1_neuro->extraProperties().set(i,colon+1);441 } 442 else if (isupper(begin[0]) || strchr("*|@",begin[0]))443 { 444 SString clsname(begin,colon-begin);445 trim(clsname);446 Neuro *receptor=model.addNewNeuro();447 receptor->setClassName(clsname);448 NeuroClass *cls=receptor->getClass();449 if (cls)450 { 451 if (cls->getPreferredLocation()==2) receptor->attachToJoint(getLastJoint());452 else if (cls->getPreferredLocation()==1) receptor->attachToPart(getLastPart());453 } 454 last_f1_neuro->addInput(receptor,ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));455 if (usemapping) receptor->addMapping(*makeRange(begin,end-1));456 } 457 else if ((begin[0]=='>')&&(begin[1]))458 { 459 Neuro *out=model.addNewNeuro();460 out->addInput(last_f1_neuro,ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));461 out->setClassName(SString(begin+1,end-colon-1));462 if (begin[1]=='@')463 { 464 sprintf(tmp,"p=%lg",lastjoint_muscle_power);465 out->setClassParams(tmp);466 } 467 else if (begin[1]=='|')468 { 469 sprintf(tmp,"p=%lg,r=%lg",lastjoint_muscle_power,props.bendrange);470 out->setClassParams(tmp);471 } 472 NeuroClass *cls=out->getClass();473 if (cls)474 { 475 if (cls->getPreferredLocation()==2) out->attachToJoint(getLastJoint());476 else if (cls->getPreferredLocation()==1) out->attachToPart(getLastPart());477 } 478 if (usemapping) out->addMapping(*makeRange(begin,end-1));479 } 480 else if (*begin=='!') addClassParam("fo",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));481 else if (*begin=='=') addClassParam("in",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));482 else if (*begin=='/') addClassParam("si",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));483 else if (islower(begin[0]))484 { 485 SString name(begin,colon-begin);486 SString value(colon+1,end-(colon+1));487 addClassParam(name.c_str(),value.c_str());488 } 489 } 425 t++; 426 } 427 SAFEDELETE(neuro_cls_param); 428 return t; 429 } 430 void Builder::growConnection(const char* begin, const char* colon, const char* end, F1Props& props) 431 { 432 while (*begin && *begin <= ' ') begin++; 433 int i; 434 if (isdigit(begin[0]) || (begin[0] == '-')) 435 { 436 double conn_weight = ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str()); 437 paInt relative = ExtValue::getInt(trim(SString(begin, colon - begin)).c_str(), false); 438 int this_refno = neuro_f1_to_f0.size() - 1; 439 addOrRememberInput(this_refno, this_refno + relative, conn_weight); 440 } 441 else if ((i = last_f1_neuro->extraProperties().findIdn(begin, colon - begin)) >= 0) 442 { 443 last_f1_neuro->extraProperties().set(i, colon + 1); 444 } 445 else if (isupper(begin[0]) || strchr("*|@", begin[0])) 446 { 447 SString clsname(begin, colon - begin); 448 trim(clsname); 449 Neuro *receptor = model.addNewNeuro(); 450 receptor->setClassName(clsname); 451 NeuroClass *cls = receptor->getClass(); 452 if (cls) 453 { 454 if (cls->getPreferredLocation() == 2) receptor->attachToJoint(getLastJoint()); 455 else if (cls->getPreferredLocation() == 1) receptor->attachToPart(getLastPart()); 456 } 457 last_f1_neuro->addInput(receptor, ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 458 if (usemapping) receptor->addMapping(*makeRange(begin, end - 1)); 459 } 460 else if ((begin[0] == '>') && (begin[1])) 461 { 462 Neuro *out = model.addNewNeuro(); 463 out->addInput(last_f1_neuro, ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 464 out->setClassName(SString(begin + 1, end - colon - 1)); 465 if (begin[1] == '@') 466 { 467 sprintf(tmp, "p=%lg", lastjoint_muscle_power); 468 out->setClassParams(tmp); 469 } 470 else if (begin[1] == '|') 471 { 472 sprintf(tmp, "p=%lg,r=%lg", lastjoint_muscle_power, props.muscle_bend_range); 473 out->setClassParams(tmp); 474 } 475 NeuroClass *cls = out->getClass(); 476 if (cls) 477 { 478 if (cls->getPreferredLocation() == 2) out->attachToJoint(getLastJoint()); 479 else if (cls->getPreferredLocation() == 1) out->attachToPart(getLastPart()); 480 } 481 if (usemapping) out->addMapping(*makeRange(begin, end - 1)); 482 } 483 else if (*begin == '!') addClassParam("fo", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 484 else if (*begin == '=') addClassParam("in", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 485 else if (*begin == '/') addClassParam("si", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 486 else if (islower(begin[0])) 487 { 488 SString name(begin, colon - begin); 489 SString value(colon + 1, end - (colon + 1)); 490 addClassParam(name.c_str(), value.c_str()); 491 } 492 } -
cpp/frams/genetics/f1/conv_f1.h
r408 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 11 11 struct F1Props 12 12 { 13 double dlug,skr,masa,tarcie,ruch,asym,odpor,wchl,rot,energ;14 double bendrange;15 int resetrange;16 double grub,cred,cgreen,cblue;17 void wykluczanie();13 double length, curvedness, weight, friction, muscle_power, assimilation, stamina, ingestion, twist, energy; 14 double muscle_bend_range; 15 bool muscle_reset_range; 16 double visual_size, cred, cgreen, cblue; 17 void normalizeBiol4(); 18 18 }; 19 19 … … 49 49 Another example: 50 50 51 "X[G][-1:2.3][-2:3.4]" - The first neuron is the standalone G receptor. Other neuron can use its output 51 "X[G][-1:2.3][-2:3.4]" - The first neuron is the standalone G receptor. Other neuron can use its output 52 52 signal by specifying it as regular input ("-1:2.3" and "-2:3.4"). This NN contains 3 neurons. 53 53 \image html nn-ex3.gif … … 57 57 Adding another neuron with "G" input will add another gyroscope object. This NN contains 4 neurons 58 58 (or 2 neurons if you try it in Framsticks v1). 59 60 61 */62 class GenoConv_f1 : public GenoConverter59 \image html nn-ex4.gif 60 61 */ 62 class GenoConv_f1 : public GenoConverter 63 63 { 64 64 public: 65 GenoConv_f1()65 GenoConv_f1() 66 66 { 67 name="Recursive encoding";68 in_format='1';69 mapsupport=1;67 name = "Recursive encoding"; 68 in_format = '1'; 69 mapsupport = 1; 70 70 } 71 SString convert(SString &i,MultiMap *map);72 ~GenoConv_f1() {}71 SString convert(SString &i, MultiMap *map); 72 ~GenoConv_f1() {} 73 73 }; 74 74 -
cpp/frams/genetics/f4/conv_f4.cpp
r534 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 179 179 // coordinates are left to be computed by Model 180 180 sprintf(tmpLine, "p:fr=%g,ing=%g,as=%g", 181 /*1.0/C->P.mass,*/ C->P.friction, C->P.ingest , C->P.assim181 /*1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation 182 182 //C->firstend.x, C->firstend.y, C->firstend.z 183 183 ); … … 196 196 sprintf(tmpLine, "p:fr=%g,ing=%g,as=%g", 197 197 //C->lastend.x, C->lastend.y, C->lastend.z 198 /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingest , C->P.assim198 /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation 199 199 ); 200 200 partidx = singleStepBuild(tmpLine, &range); … … 212 212 // relative position -- always (len, 0, 0), along the stick 213 213 // this is optional! 214 C->P.len ,214 C->P.length, 215 215 // relative rotation 216 216 C->xrot, C->zrot, 217 217 //C->P.ruch, // rotstif 218 C->P. odpor218 C->P.stamina 219 219 ); 220 220 partidx = singleStepBuild(tmpLine, &range); … … 241 241 { 242 242 if (1 == C->ctrl) 243 sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P. ruch);243 sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.muscle_power); 244 244 else 245 sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P. ruch, C->mz);245 sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P.muscle_power, C->mz); 246 246 partidx = singleStepBuild(tmpLine, &range); 247 247 if (partidx < 0) return -32; -
cpp/frams/genetics/f4/f4_general.cpp
r375 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 20 20 f4_Props::f4_Props() 21 21 { 22 len = 1.0;23 curv = 0.0;24 mass= 1.0;22 length = 1.0; 23 curvedness = 0.0; 24 weight = 1.0; 25 25 friction = 0.4; 26 ruch = 0.25; // bio27 assim = 0.25; // bio28 odpor = 0.25; // bio29 ingest = 0.25; // bio26 muscle_power = 0.25; // biol 27 assimilation = 0.25; // biol 28 stamina = 0.25; // biol 29 ingestion = 0.25; // biol 30 30 twist = 0.0; 31 energ = 1.0;31 energy = 1.0; 32 32 normalizeBiol4(); 33 33 } … … 35 35 void f4_Props::normalizeBiol4() 36 36 { 37 // must sum to 1 38 double sum = ruch + assim + odpor + ingest; 39 if (0 == sum) 40 { 41 ruch = assim = odpor = ingest = 0.25; 42 } 43 else { 44 ruch /= sum; 45 assim /= sum; 46 odpor /= sum; 47 ingest /= sum; 37 // make them sum to 1 38 double sum = muscle_power + assimilation + stamina + ingestion; 39 if (sum == 0) 40 { 41 muscle_power = assimilation = stamina = ingestion = 0.25; 42 } 43 else 44 { 45 muscle_power /= sum; 46 assimilation /= sum; 47 stamina /= sum; 48 ingestion /= sum; 48 49 } 49 50 } … … 53 54 switch (modif) 54 55 { 55 case 'L': len += (2.5 - len) * 0.3;56 len = min(len, Model::getMaxJoint().d.x); break;57 case 'l': len += (0.3 - len) * 0.3;58 len = max(len, Model::getMinJoint().d.x); break;59 case 'C': curv += (2.0 - curv) * 0.25; break;60 case 'c': curv += (-2.0 - curv) * 0.25; break;56 case 'L': length += (2.5 - length) * 0.3; 57 length = min(length, Model::getMaxJoint().d.x); break; 58 case 'l': length += (0.3 - length) * 0.3; 59 length = max(length, Model::getMinJoint().d.x); break; 60 case 'C': curvedness += (2.0 - curvedness) * 0.25; break; 61 case 'c': curvedness += (-2.0 - curvedness) * 0.25; break; 61 62 case 'Q': twist += (1.58 - twist) * 0.3; break; 62 63 case 'q': twist += (-1.58 - twist) * 0.3; break; 63 case 'A': assim += (1 - assim) * 0.8; normalizeBiol4(); break;64 case 'a': assim -= assim* 0.4; normalizeBiol4(); break;65 case 'I': ingest += (1 - ingest) * 0.8; normalizeBiol4(); break;66 case 'i': ingest -= ingest* 0.4; normalizeBiol4(); break;67 case 'S': odpor += (1 - odpor) * 0.8; normalizeBiol4(); break;68 case 's': odpor -= odpor* 0.4; normalizeBiol4(); break;69 case 'M': ruch += (1 - ruch) * 0.8; normalizeBiol4(); break;70 case 'm': ruch -= ruch* 0.4; normalizeBiol4(); break;64 case 'A': assimilation += (1 - assimilation) * 0.8; normalizeBiol4(); break; 65 case 'a': assimilation -= assimilation * 0.4; normalizeBiol4(); break; 66 case 'I': ingestion += (1 - ingestion) * 0.8; normalizeBiol4(); break; 67 case 'i': ingestion -= ingestion * 0.4; normalizeBiol4(); break; 68 case 'S': stamina += (1 - stamina) * 0.8; normalizeBiol4(); break; 69 case 's': stamina -= stamina * 0.4; normalizeBiol4(); break; 70 case 'M': muscle_power += (1 - muscle_power) * 0.8; normalizeBiol4(); break; 71 case 'm': muscle_power -= muscle_power * 0.4; normalizeBiol4(); break; 71 72 case 'F': friction += (4 - friction) * 0.2; break; 72 73 case 'f': friction -= friction * 0.2; break; 73 case 'W': mass += (2.0 - mass) * 0.3; break;74 case 'w': mass += (0.5 - mass) * 0.3; break;75 case 'E': energ += (10.0 - energ) * 0.1; break;76 case 'e': energ -= energ* 0.1; break;74 case 'W': weight += (2.0 - weight) * 0.3; break; 75 case 'w': weight += (0.5 - weight) * 0.3; break; 76 case 'E': energy += (10.0 - energy) * 0.1; break; 77 case 'e': energy -= energy * 0.1; break; 77 78 } 78 79 } … … 80 81 void f4_Props::adjust() 81 82 { 82 len = 0.5*len + 0.5*stdProps.len;83 curv = 0.66 * curv;83 length = 0.5*length + 0.5*stdProps.length; 84 curvedness = 0.66 * curvedness; 84 85 twist = 0.66 * twist; 85 86 } … … 88 89 89 90 90 void rolling_dec(double * v) { 91 void rolling_dec(double * v) 92 { 91 93 *v -= 0.7853; // 0.7853981 45 degrees 92 94 } 93 void rolling_inc(double * v) { 95 96 void rolling_inc(double * v) 97 { 94 98 *v += 0.7853; // 0.7853981 45 degrees 95 99 } … … 106 110 if (stopchar == s[i]) // bumped into stopchar 107 111 return i; 108 if (i < slen - 1) 109 { // s[i] is not the last char112 if (i < slen - 1) // s[i] is not the last char 113 { 110 114 if (s[i] == '(') 111 115 { … … 183 187 184 188 185 f4_Cell::f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur, 186 f4_Cell * ndad, int nangle, f4_Props newP) 189 f4_Cell::f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur, f4_Cell * ndad, int nangle, f4_Props newP) 187 190 { 188 191 name = nname; … … 218 221 { 219 222 // make sure it is a stick (and not a stick f4_Cell!) 220 if (T_STICK4 == ndad->type) { 223 if (T_STICK4 == ndad->type) 224 { 221 225 //firstend = ndad->lastend; 222 226 //OM = ndad->OM; … … 279 283 280 284 // error: sticks cannot divide 281 if (T_STICK4 == type) { 285 if (T_STICK4 == type) 286 { 282 287 // cannot fix 283 288 org->setError(gcur->pos); … … 286 291 287 292 // undiff divides 288 if (T_UNDIFF4 == type) { 293 if (T_UNDIFF4 == type) 294 { 289 295 // commacount is set only when daughter turns into X 290 296 // daughter cell … … 292 298 f4_Props newP = P; 293 299 newP.adjust(); 294 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, 295 this, commacount, newP); 300 tmp = new f4_Cell(org, org->nc, genot, gcur->child2, this, commacount, newP); 296 301 tmp->repeat = repeat; 297 302 repeat.null(); … … 310 315 // duplicate links 311 316 f4_CellLink * ll; 312 for (i = 0; i < nolink; i++) { 317 for (i = 0; i < nolink; i++) 318 { 313 319 ll = links[i]; 314 320 tmp->addlink(ll->from, ll->w, ll->t); … … 334 340 gcur = repeat.first()->node->child; 335 341 } 336 else { 342 else 343 { 337 344 // continue 338 345 gcur = repeat.first()->node->child2; … … 341 348 break; 342 349 } 343 else { 350 else 351 { 344 352 repeat.pop(); 345 353 } 346 354 } 347 else { 355 else 356 { 348 357 // error: still undiff 349 358 if (T_UNDIFF4 == type) … … 351 360 // fix it: insert an 'X' 352 361 f4_node * insertnode = new f4_node('X', NULL, gcur->pos); 353 if (org->setRepairInsert(gcur->pos, gcur, insertnode)) 354 // not in repair mode, release 362 if (org->setRepairInsert(gcur->pos, gcur, insertnode)) // not in repair mode, release 355 363 delete insertnode; 356 364 return 1; … … 383 391 case 'r': case 'R': 384 392 // error: if neuron 385 if (T_NEURON4 == type) { 393 if (T_NEURON4 == type) 394 { 386 395 // fix: delete it 387 396 org->setRepairRemove(gcur->pos, gcur); 388 397 return 1; // stop 389 398 } 390 switch (gcur->name) { 399 switch (gcur->name) 400 { 391 401 case 'r': rolling_dec(&rolling); break; 392 402 case 'R': rolling_inc(&rolling); break; … … 406 416 case 'e': case 'E': 407 417 // error: if neuron 408 if (T_NEURON4 == type) { 418 if (T_NEURON4 == type) 419 { 409 420 // fix: delete it 410 421 org->setRepairRemove(gcur->pos, gcur); … … 418 429 // turn undiff. cell into a stick 419 430 // error: already differentiated 420 if (T_UNDIFF4 != type) { 431 if (T_UNDIFF4 != type) 432 { 421 433 // fix: delete this node 422 434 org->setRepairRemove(gcur->pos, gcur); … … 425 437 type = T_STICK4; 426 438 // fix dad commacount and own anglepos 427 if (NULL != dadlink) { 439 if (NULL != dadlink) 440 { 428 441 dadlink->commacount++; 429 442 anglepos = dadlink->commacount; … … 436 449 // turn undiff. cell into a neuron 437 450 // error: already differentiated 438 if (T_UNDIFF4 != type) { 451 if (T_UNDIFF4 != type) 452 { 439 453 // fix: delete this node 440 454 org->setRepairRemove(gcur->pos, gcur); … … 442 456 } 443 457 // error: if no previous 444 if (NULL == dadlink) { 458 if (NULL == dadlink) 459 { 445 460 // fix: delete it 446 461 org->setRepairRemove(gcur->pos, gcur); … … 461 476 if ('|' == gcur->name) j = 2; // bend 462 477 // error: not a neuron (undiff) 463 if (T_UNDIFF4 == type) { 478 if (T_UNDIFF4 == type) 479 { 464 480 // fix: delete it 465 481 org->setRepairRemove(gcur->pos, gcur); … … 467 483 } 468 484 // error: not a neuron (stick) 469 if (T_NEURON4 != type) { 485 if (T_NEURON4 != type) 486 { 470 487 // fix: delete it 471 488 org->setRepairRemove(gcur->pos, gcur); … … 473 490 } 474 491 // error: already has control 475 if (ctrl != 0) { 492 if (ctrl != 0) 493 { 476 494 // fix: delete it 477 495 org->setRepairRemove(gcur->pos, gcur); … … 486 504 // link to neuron 487 505 // error: not a neuron 488 if (T_NEURON4 != type) { 506 if (T_NEURON4 != type) 507 { 489 508 // fix: delete it 490 509 org->setRepairRemove(gcur->pos, gcur); … … 495 514 relfrom = gcur->l1; 496 515 w = gcur->f1; 497 if (t > 0) { 516 if (t > 0) 517 { 498 518 // * or G 499 519 tneu = NULL; … … 504 524 // find own index 505 525 j = 0; k = 0; 506 for (i = 0; i < org->nc; i++) { 526 for (i = 0; i < org->nc; i++) 527 { 507 528 if (org->C[i]->type == T_NEURON4) k++; 508 529 if (org->C[i] == this) { j = k - 1; break; } … … 514 535 // find that neuron 515 536 k = 0; 516 for (i = 0; i < org->nc; i++) { 537 for (i = 0; i < org->nc; i++) 538 { 517 539 if (org->C[i]->type == T_NEURON4) k++; 518 540 if (j == (k - 1)) break; … … 523 545 // add link 524 546 // error: could not add link (too many?) 525 if (addlink(tneu, w, t)) { 547 if (addlink(tneu, w, t)) 548 { 526 549 // cannot fix 527 550 org->setError(gcur->pos); … … 535 558 active = 0; 536 559 j = 0; 537 for (i = 0; i<org->nc; i++) { 560 for (i = 0; i < org->nc; i++) 561 { 538 562 if (org->C[i]->active) j++; 539 563 } 540 if (j >0)564 if (j > 0) 541 565 return 0; // there is other active, halt, try again 542 566 // no more actives, cannot add link, ignore, but treat not as an error … … 547 571 // neuron parameter 548 572 // error: not a neuron 549 if (T_NEURON4 != type) { 573 if (T_NEURON4 != type) 574 { 550 575 // fix: delete it 551 576 org->setRepairRemove(gcur->pos, gcur); … … 553 578 } 554 579 j = (int)gcur->l1; 555 switch ((char)gcur->i1) { 580 switch ((char)gcur->i1) 581 { 556 582 case '!': 557 583 if (j) force += (1.0 - force) * 0.2; … … 604 630 { 605 631 //f4_OrientMat rot; 606 int 632 int i; 607 633 608 634 if (recProcessedFlag) … … 635 661 mz = 1; 636 662 } 637 else { 663 else 664 { 638 665 //firstend = dadlink->lastend; 639 666 f4_Props Pdad = dadlink->P; … … 650 677 { 651 678 // rotation due to curvedness 652 zrot = Padj.curv; 653 } 654 else { 655 zrot = Padj.curv + 656 // SDK uses 3.141 instead of PI! 657 (anglepos * 1.0 / (dadlink->commacount + 1) - 0.5) * 3.141 * 2.0; 679 zrot = Padj.curvedness; 680 } 681 else 682 { 683 zrot = Padj.curvedness + (anglepos * 1.0 / (dadlink->commacount + 1) - 0.5) * M_PI * 2.0; 658 684 } 659 685 … … 722 748 723 749 // create ancestor cell 724 C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child, 725 NULL, 0, stdProps); 750 C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child, NULL, 0, stdProps); 726 751 nc = 1; 727 752 } … … 747 772 oldnc = nc; 748 773 ret = 0; 749 for (i = 0; i<oldnc; i++) { 774 for (i = 0; i < oldnc; i++) 775 { 750 776 ret2 = C[i]->onestep(); 751 if (ret2>0) { 777 if (ret2 > 0) 778 { 752 779 // error 753 780 C[i]->active = 0; // stop … … 776 803 // fix neuron attachements 777 804 for (i = 0; i < nc; i++) 778 if (C[i]->type == T_NEURON4) { 779 while (T_NEURON4 == C[i]->dadlink->type) { 805 { 806 if (C[i]->type == T_NEURON4) 807 { 808 while (T_NEURON4 == C[i]->dadlink->type) 809 { 780 810 C[i]->dadlink = C[i]->dadlink->dadlink; 781 811 } 782 812 } 813 } 783 814 784 815 // there should be no undiff. cells 785 816 // make undifferentiated cells sticks 786 817 for (i = 0; i < nc; i++) 787 if (C[i]->type == T_UNDIFF4) { 818 { 819 if (C[i]->type == T_UNDIFF4) 820 { 788 821 C[i]->type = T_STICK4; 789 822 //seterror(); 790 823 } 824 } 791 825 792 826 // recursive adjust … … 806 840 void f4_Cells::addCell(f4_Cell * newcell) 807 841 { 808 if (nc >= MAX4CELLS - 1) { 842 if (nc >= MAX4CELLS - 1) 843 { 809 844 delete newcell; 810 845 return; … … 823 858 void f4_Cells::setRepairRemove(int nerrpos, f4_node * rem) 824 859 { 825 if (!repair) { 860 if (!repair) 861 { 826 862 // not in repair mode, treat as repairable error 827 863 error = GENOPER_REPAIR; 828 864 errorpos = nerrpos; 829 865 } 830 else { 866 else 867 { 831 868 error = GENOPER_REPAIR; 832 869 errorpos = nerrpos; … … 837 874 int f4_Cells::setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert) 838 875 { 839 if (!repair) { 876 if (!repair) 877 { 840 878 // not in repair mode, treat as repairable error 841 879 error = GENOPER_REPAIR; … … 843 881 return -1; 844 882 } 845 else { 883 else 884 { 846 885 error = GENOPER_REPAIR; 847 886 errorpos = nerrpos; … … 863 902 if (NULL == g2) 864 903 return; 865 if (g2 == repair_remove) { 904 if (g2 == repair_remove) 905 { 866 906 f4_node * oldgeno; 867 907 geno->removeChild(g2); 868 if (g2->child) { 908 if (g2->child) 909 { 869 910 // add g2->child as child to geno 870 911 if (1 == whichchild) geno->child = g2->child; … … 880 921 return; 881 922 } 882 if (g2 == repair_parent) { 923 if (g2 == repair_parent) 924 { 883 925 geno->removeChild(g2); 884 926 geno->addChild(repair_insert); … … 921 963 // adjust length, curvedness, etc. 922 964 tmpcel->P.adjust(); 923 while (tmpcel->P.len > thisti->P.len)965 while (tmpcel->P.length > thisti->P.length) 924 966 { 925 967 tmpcel->P.executeModifier('l'); 926 968 out += "l"; 927 969 } 928 while (tmpcel->P.len < thisti->P.len)970 while (tmpcel->P.length < thisti->P.length) 929 971 { 930 972 tmpcel->P.executeModifier('L'); 931 973 out += "L"; 932 974 } 933 while (tmpcel->P.curv > thisti->P.curv)975 while (tmpcel->P.curvedness > thisti->P.curvedness) 934 976 { 935 977 tmpcel->P.executeModifier('c'); 936 978 out += "c"; 937 979 } 938 while (tmpcel->P.curv < thisti->P.curv)980 while (tmpcel->P.curvedness < thisti->P.curvedness) 939 981 { 940 982 tmpcel->P.executeModifier('C'); 941 983 out += "C"; 942 984 } 943 while (thisti->rolling > 0.0f) { 985 while (thisti->rolling > 0.0f) 986 { 944 987 rolling_dec(&(thisti->rolling)); 945 988 out += "R"; 946 989 } 947 while (thisti->rolling < 0.0f) { 990 while (thisti->rolling < 0.0f) 991 { 948 992 rolling_inc(&(thisti->rolling)); 949 993 out += "r"; … … 955 999 // neurons attached to it 956 1000 for (i = 0; i < nc; i++) 957 if (C[i]->type == T_NEURON4) { 958 if (C[i]->dadlink == thisti) { 1001 { 1002 if (C[i]->type == T_NEURON4) 1003 { 1004 if (C[i]->dadlink == thisti) 1005 { 959 1006 thneu = C[i]; 960 1007 out += "["; … … 974 1021 if (4 == thneu->links[j]->t) out += "S"; 975 1022 } 976 else { 1023 else 1024 { 977 1025 sprintf(buf, "%d", thneu->links[j]->from->name - thneu->name); 978 1026 out += buf; 979 1027 } 980 1028 out += ":"; 981 // weight1029 // connection weight 982 1030 sprintf(buf, "%g", thneu->links[j]->w); 983 1031 out += buf; … … 986 1034 } 987 1035 } 1036 } 988 1037 989 1038 // sticks connected to it … … 993 1042 ccount = 1; 994 1043 for (i = 0; i < nc; i++) 1044 { 995 1045 if (C[i]->type == T_STICK4) 996 if (C[i]->dadlink == thisti) { 997 while (ccount < (C[i])->anglepos) { 1046 { 1047 if (C[i]->dadlink == thisti) 1048 { 1049 while (ccount < (C[i])->anglepos) 1050 { 998 1051 ccount++; 999 1052 out += ","; … … 1001 1054 toF1GenoRec(i, out); 1002 1055 } 1003 while (ccount < thisti->commacount) { 1056 } 1057 } 1058 1059 while (ccount < thisti->commacount) 1060 { 1004 1061 ccount++; 1005 1062 out += ","; … … 1012 1069 1013 1070 1014 // to organize a f4 genotype in a tree structure1071 // to organize an f4 genotype in a tree structure 1015 1072 1016 1073 f4_node::f4_node() … … 1043 1100 int f4_node::addChild(f4_node * nchi) 1044 1101 { 1045 if (NULL == child) { 1102 if (NULL == child) 1103 { 1046 1104 child = nchi; 1047 1105 return 0; 1048 1106 } 1049 if (NULL == child2) { 1107 if (NULL == child2) 1108 { 1050 1109 child2 = nchi; 1051 1110 return 0; … … 1056 1115 int f4_node::removeChild(f4_node * nchi) 1057 1116 { 1058 if (nchi == child2) { 1117 if (nchi == child2) 1118 { 1059 1119 child2 = NULL; 1060 1120 return 0; 1061 1121 } 1062 if (nchi == child) { 1122 if (nchi == child) 1123 { 1063 1124 child = NULL; 1064 1125 return 0; … … 1069 1130 int f4_node::childCount() 1070 1131 { 1071 if (NULL != child) { 1132 if (NULL != child) 1133 { 1072 1134 if (NULL != child2) return 2; 1073 1135 else return 1; 1074 1136 } 1075 else { 1137 else 1138 { 1076 1139 if (NULL != child2) return 1; 1077 1140 else return 0; … … 1092 1155 if (0 == n) return this; 1093 1156 n--; 1094 if (NULL != child) { 1157 if (NULL != child) 1158 { 1095 1159 n1 = child->count(); 1096 1160 if (n < n1) return child->ordNode(n); 1097 1161 n -= n1; 1098 1162 } 1099 if (NULL != child2) { 1163 if (NULL != child2) 1164 { 1100 1165 n1 = child2->count(); 1101 1166 if (n < n1) return child2->ordNode(n); … … 1119 1184 f4_node * nod = NULL; 1120 1185 maxlim = count(); 1121 for (i = 0; i < maxlim; i++) { 1186 for (i = 0; i < maxlim; i++) 1187 { 1122 1188 nod = randomNode(); 1123 1189 n = nod->count(); … … 1135 1201 { 1136 1202 out += "#"; 1137 if (i1 != 1) { 1203 if (i1 != 1) 1204 { 1138 1205 sprintf(buf2, "%d", i1); 1139 1206 out += buf2; … … 1142 1209 else { 1143 1210 // special case: neuron link 1144 if ('[' == name) { 1211 if ('[' == name) 1212 { 1145 1213 out += "["; 1146 if (i1 > 0) { 1214 if (i1 > 0) 1215 { 1147 1216 // sensor input 1148 1217 if (1 == i1) out += "*"; … … 1151 1220 if (4 == i1) out += "S"; 1152 1221 } 1153 else { 1222 else 1223 { 1154 1224 sprintf(buf2, "%ld", l1); 1155 1225 out += buf2; … … 1158 1228 out += buf2; 1159 1229 } 1160 else if (':' == name) { 1230 else if (':' == name) 1231 { 1161 1232 sprintf(buf2, ":%c%c:", l1 ? '+' : '-', (char)i1); 1162 1233 out += buf2; 1163 1234 } 1164 else { 1235 else 1236 { 1165 1237 buf2[0] = name; 1166 1238 buf2[1] = 0; … … 1194 1266 // copy back to string 1195 1267 // if new is longer, reallocate buf 1196 if (len + 1 > strlen(buf)) { 1268 if (len + 1 > strlen(buf)) 1269 { 1197 1270 buf = (char*)realloc(buf, len + 1); 1198 1271 } … … 1207 1280 copy->child = NULL; 1208 1281 copy->child2 = NULL; 1209 if (NULL != child) { 1282 if (NULL != child) 1283 { 1210 1284 copy->child = child->duplicate(); 1211 1285 copy->child->parent = copy; 1212 1286 } 1213 if (NULL != child2) { 1287 if (NULL != child2) 1288 { 1214 1289 copy->child2 = child2->duplicate(); 1215 1290 copy->child2->parent = copy; … … 1241 1316 par = parent; 1242 1317 if (gpos >= strlen(genot)) return 1; 1243 while (gpos < strlen(genot)) { 1318 while (gpos < strlen(genot)) 1319 { 1244 1320 //DB( printf(" processing '%c' %d %s\n", genot[gpos], gpos, genot); ) 1245 switch (genot[gpos]) { 1321 switch (genot[gpos]) 1322 { 1246 1323 case '<': 1247 1324 // cell division! … … 1255 1332 res = f4_processrec(genot, gpos + 1, par); 1256 1333 if (res) return res; 1257 if (gpos + j + 2 < strlen(genot)) { 1334 if (gpos + j + 2 < strlen(genot)) 1335 { 1258 1336 res = f4_processrec(genot, gpos + j + 2, par); 1259 1337 if (res) return res; 1260 1338 } 1261 else { // ran out 1339 else // ran out 1340 { 1262 1341 node1 = new f4_node('>', par, strlen(genot) - 1); 1263 1342 par = node1; … … 1287 1366 res = f4_processrec(genot, gpos, node1); 1288 1367 if (res) return res; 1289 if (oldpos + j + 2 < strlen(genot)) { 1368 if (oldpos + j + 2 < strlen(genot)) 1369 { 1290 1370 res = f4_processrec(genot, oldpos + j + 2, node1); 1291 1371 if (res) return res; 1292 1372 } 1293 else { // ran out 1373 else // ran out 1374 { 1294 1375 node1 = new f4_node('>', par, strlen(genot) - 1); 1295 1376 } … … 1344 1425 else if ('-' == tc1) j = 0; 1345 1426 else return gpos + 1 + 1; 1346 switch (tc2) { 1427 switch (tc2) 1428 { 1347 1429 case '!': case '=': case '/': break; 1348 1430 default: … … 1377 1459 // should end with a '>' 1378 1460 if (par) 1379 if ('>' != par->name) { 1461 { 1462 if ('>' != par->name) 1463 { 1380 1464 node1 = new f4_node('>', par, strlen(genot) - 1); 1381 1465 par = node1; 1382 1466 } 1467 } 1468 1383 1469 return 0; // OK 1384 1470 } … … 1394 1480 //DB( printf("test f4 "); ) 1395 1481 DB( 1396 if (root->child) { 1397 char * buf = (char*)malloc(300); 1398 DB(printf("(%d) ", root->child->count());) 1399 buf[0] = 0; 1400 root->child->sprintAdj(buf); 1401 DB(printf("%s\n", buf);) 1402 free(buf); 1482 if (root->child) 1483 { 1484 char * buf = (char*)malloc(300); 1485 DB(printf("(%d) ", root->child->count());) 1486 buf[0] = 0; 1487 root->child->sprintAdj(buf); 1488 DB(printf("%s\n", buf);) 1489 free(buf); 1403 1490 } 1404 1491 ) -
cpp/frams/genetics/f4/f4_general.h
r286 r671 28 28 void adjust(); 29 29 30 double len ; // length (dlug)31 double curv ; // curvedness (skr)32 double mass;30 double length; 31 double curvedness; 32 double weight; 33 33 double friction; 34 double ruch;35 double assim ;36 double odpor;37 double ingest ; // ingestion (wchl)34 double muscle_power; 35 double assimilation; 36 double stamina; 37 double ingestion; 38 38 double twist; 39 double energ ;39 double energy; 40 40 }; 41 41 -
cpp/frams/genetics/f4/oper_f4.cpp
r513 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 231 231 // must pick a node with parent, and at least one child 232 232 // already picked a node, but repeat may be needed 233 for (int i = 0; i < 10; i++) { 233 for (int i = 0; i < 10; i++) 234 { 234 235 if ((NULL != n1->parent) && (g != n1->parent)) 235 236 if (NULL != n1->child) … … 247 248 n2 = n1->parent; 248 249 n2->removeChild(n1); 249 if (NULL != n1->child) { 250 if (NULL != n1->child) 251 { 250 252 n1->child->parent = n2; 251 253 n2->addChild(n1->child); 252 254 n1->child = NULL; 253 255 } 254 if (NULL != n1->child2) { 256 if (NULL != n1->child2) 257 { 255 258 n1->child2->parent = n2; 256 259 n2->addChild(n1->child2); … … 309 312 if (i >= 20) return GENOPER_OPFAIL; 310 313 } 311 switch (n1->name) { 314 switch (n1->name) 315 { 312 316 case '<': 313 317 // swap children … … 348 352 nn->i1 = i; 349 353 nn->l1 = 0; 350 if (0 == i) { 354 if (0 == i) 355 { 351 356 // relative input link 352 357 nn->l1 = (int)(4.0f * (rnd01 - 0.5f)); … … 407 412 if (prob1 < 0.5f) count++; 408 413 else count--; 409 if (count <1) count = 1;410 if (count >REP_MAXCOUNT) count = REP_MAXCOUNT;414 if (count < 1) count = 1; 415 if (count > REP_MAXCOUNT) count = REP_MAXCOUNT; 411 416 nn->i1 = count; 412 417 } … … 464 469 if (f4_processrec(g, 0, root) || root->childCount() != 1) 465 470 { 466 delete root; return GENOPER_OPFAIL; 471 delete root; 472 return GENOPER_OPFAIL; 467 473 } // could not convert or bad: fail 468 474 // mutate one node, set chg as this percent … … 470 476 if (MutateOneValid(root, method) != GENOPER_OK) 471 477 { 472 delete root; return GENOPER_OPFAIL; 478 delete root; 479 return GENOPER_OPFAIL; 473 480 } 474 481 // OK, convert back to string -
cpp/frams/genetics/f4/oper_f4.h
r513 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4
Note: See TracChangeset
for help on using the changeset viewer.