source: cpp/frams/genetics/geneprops.cpp @ 1242

Last change on this file since 1242 was 1242, checked in by Maciej Komosinski, 2 years ago

Changed the default behavior of modifier genes in f1 and f4 to GenePropsOps_New05: the coefficient of change is set to 0.5 for all properties and for both increase and decrease, which ensures an equal distribution of target property values with a relatively fast convergence to minimal and maximal values; the four "biological" properties are no longer aggregated and normalized

File size: 9.2 KB
RevLine 
[759]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[1242]2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
[759]3// See LICENSE.txt for details.
4
5#include "geneprops.h"
[1130]6#include <algorithm>
[759]7
8GeneProps GeneProps::standard_values;
9
10GeneProps::GeneProps()
11{
12        length = 1.0;
13        weight = 1.0;
14        friction = 0.4;
15        curvedness = 0.0;
16        twist = 0.0;
17        energy = 1.0;
18
19        muscle_power = 0.25; // "biological" property
20        assimilation = 0.25; // "biological" property
21        stamina = 0.25; // "biological" property
22        ingestion = 0.25; // "biological" property
23
24        muscle_bend_range = 1.0;
25        muscle_reset_range = true;
26
27        cred = 0.5;
28        cgreen = 0.5;
29        cblue = 0.5;
30
31        normalizeBiol4();
32}
33
34void GeneProps::normalizeBiol4()
35{
36        // make them sum to 1
37        double sum = muscle_power + assimilation + stamina + ingestion;
38        if (sum == 0)
39        {
40                muscle_power = assimilation = stamina = ingestion = 0.25;
41        }
42        else
43        {
44                muscle_power /= sum;
45                assimilation /= sum;
46                stamina /= sum;
47                ingestion /= sum;
48        }
49}
50
[1242]51int GeneProps::executeModifier_Legacy(char modif)
[759]52{
53        switch (modif)
54        {
55#ifdef v1f1COMPATIBLE
[1242]56        case 'L': length += (3.0 - length) * 0.3;
[1130]57                length = std::min(length, Model::getMaxJoint().d.x); break;
[759]58#else
[1242]59        case 'L': length += (2.0 - length) * 0.3; //2.0 is currently Model::getMaxJoint().d.x so min() does not limit the range
[1130]60                length = std::min(length, Model::getMaxJoint().d.x); break;
[759]61#endif
[1242]62        case 'l': length += (0.33 - length) * 0.3;
[1130]63                length = std::max(length, Model::getMinJoint().d.x); break;
[759]64
[1242]65        case 'W': weight += (2.0 - weight) * 0.3; break;
66        case 'w': weight += (0.5 - weight) * 0.3; break;
67        case 'F': friction += (4 - friction) * 0.2; break;
68        case 'f': friction -= friction * 0.2; break;
[759]69        case 'C': curvedness += (2.0 - curvedness) * 0.25; break;
70        case 'c': curvedness += (-2.0 - curvedness) * 0.25; break;
[1242]71        case 'Q': twist += (M_PI_2 - twist) * 0.3; break;
72        case 'q': twist += (-M_PI_2 - twist) * 0.3; break;
73        case 'E': energy += (10.0 - energy) * 0.1; break;
74        case 'e': energy -= energy * 0.1;  break;
[759]75
[1242]76        case 'A': assimilation += (1 - assimilation) * 0.8; normalizeBiol4(); break;
77        case 'a': assimilation -= assimilation * 0.4; normalizeBiol4(); break;
78        case 'I': ingestion += (1 - ingestion) * 0.8; normalizeBiol4(); break;
79        case 'i': ingestion -= ingestion * 0.4; normalizeBiol4(); break;
80        case 'S': stamina += (1 - stamina) * 0.8; normalizeBiol4(); break;
81        case 's': stamina -= stamina * 0.4; normalizeBiol4(); break;
82        case 'M': muscle_power += (1 - muscle_power) * 0.8; normalizeBiol4(); break;
83        case 'm': muscle_power -= muscle_power * 0.4; normalizeBiol4(); break;
[759]84
[1242]85        case 'D': cred += (1.0 - cred) * 0.25; break;
86        case 'd': cred += (0.0 - cred) * 0.25; break;
87        case 'G': cgreen += (1.0 - cgreen) * 0.25; break;
88        case 'g': cgreen += (0.0 - cgreen) * 0.25; break;
89        case 'B': cblue += (1.0 - cblue) * 0.25; break;
90        case 'b': cblue += (0.0 - cblue) * 0.25; break;
[759]91
92        default: return -1;
93        }
94        return 0;
95}
96
[1242]97int GeneProps::executeModifier(char modif, GenePropsOps* ops)
98{
99        if (ops == NULL)
100                ops = getStandardOps();
101
102#define APPLY(name) ops->name->apply(name, modif)
103#define APPLY_AND_MAYBE_NORMALIZEBIOL4(name) {APPLY(name); if (ops->use_normalizebiol4) normalizeBiol4();}
104
105        switch (toupper(modif))
106        {
107        case 'L': APPLY(length);
108                length = std::min(length, Model::getMaxJoint().d.x); break;
109                break;
110
111        case 'l': APPLY(length);
112                length = std::max(length, Model::getMinJoint().d.x); break;
113                break;
114
115        case 'W': APPLY(weight); break;
116        case 'F': APPLY(friction); break;
117        case 'C': APPLY(curvedness); break;
118        case 'Q': APPLY(twist); break;
119        case 'E': APPLY(energy); break;
120
121        case 'A': APPLY_AND_MAYBE_NORMALIZEBIOL4(assimilation); break;
122        case 'I': APPLY_AND_MAYBE_NORMALIZEBIOL4(ingestion); break;
123        case 'S': APPLY_AND_MAYBE_NORMALIZEBIOL4(stamina); break;
124        case 'M': APPLY_AND_MAYBE_NORMALIZEBIOL4(muscle_power); break;
125
126        case 'D': APPLY(cred); break;
127        case 'G': APPLY(cgreen); break;
128        case 'B': APPLY(cblue); break;
129
130        default: return -1;
131        }
132        return 0;
133
134#undef APPLY
135#undef APPLY_AND_MAYBE_NORMALIZEBIOL4
136}
137
[759]138void GeneProps::propagateAlong(bool use_f1_muscle_reset_range)
139{
[1242]140        length = 0.5 * length + 0.5 * standard_values.length;
[759]141        weight += (standard_values.weight - weight) * 0.5;
142        friction = 0.8 * friction + 0.2 * standard_values.friction;
143        curvedness = 0.66 * curvedness;
144        twist = 0.66 * twist;
145
146        assimilation = 0.8 * assimilation + 0.2 * standard_values.assimilation;
147        ingestion = 0.8 * ingestion + 0.2 * standard_values.ingestion;
148        stamina = 0.8 * stamina + 0.2 * standard_values.stamina;
149        muscle_power = 0.8 * muscle_power + 0.2 * standard_values.muscle_power;
150
151        normalizeBiol4();
152
153        if (use_f1_muscle_reset_range)
154        {
155                if (muscle_reset_range) muscle_bend_range = 1.0; else muscle_reset_range = true;
156        }
157}
[1242]158
159////////////////////////////////////////////////////
160
161void GenePropsOp::apply(double &value, char modif) const
162{
163        if (isupper(modif))
164                value = increase(value);
165        else
166                value = decrease(value);
167}
168
169double GenePropsOp_Old::increase(double value) const
170{
171        return value + (maxvalue - value) * change;
172}
173
174double GenePropsOp_Old::decrease(double value) const
175{
176        return value + (minvalue - value) * revchange;
177}
178
179GenePropsOp_Old::GenePropsOp_Old(double minvalue, double maxvalue, double defvalue, double change, double revchange)
180{
181        this->minvalue = minvalue;
182        this->maxvalue = maxvalue;
183        this->defvalue = defvalue;
184        this->change = change;
185        this->revchange = (revchange < 0) ? change : revchange;
186}
187
188GenePropsOp_Exponential::GenePropsOp_Exponential(double minvalue, double maxvalue, double defvalue, double change)
189        :GenePropsOp_NormalizedAndScaled(change)
190{
191        double mid = (maxvalue + minvalue) / 2;
192        if (fabs(mid - defvalue) < 0.01)
193        {
194                linear = true;
195                a = (maxvalue - minvalue) / 2;
196                b = defvalue;
197        }
198        else
199        {
200                linear = false;
201                a = -(maxvalue - defvalue) / (minvalue - defvalue);
202                b = (minvalue * minvalue - 2 * defvalue * minvalue + defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
203                c = (maxvalue * minvalue - defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
204                log_a = log(a);
205        }
206}
207
208double GenePropsOp_Exponential::scale(double value) const
209{
210        if (linear)
211                return a * value + b;
212        else
213                return pow(a, (value + 1)) * b + c;
214}
215
216double GenePropsOp_Exponential::scaleInv(double value) const
217{
218        if (linear)
219                return (value - b) / a;
220        else
221                return -(log_a - log(value / b - c / b)) / log_a;
222}
223
224////////////////////////////////////////////////////////////////////
225
226
227GenePropsOps::~GenePropsOps()
228{
229        delete length;
230        delete curvedness;
231        delete weight;
232        delete friction;
233        delete muscle_power;
234        delete assimilation;
235        delete stamina;
236        delete ingestion;
237        delete twist;
238        delete energy;
239        delete cred;
240        delete cgreen;
241        delete cblue;
242}
243
244GenePropsOps_Old::GenePropsOps_Old()
245{
246        use_normalizebiol4 = true;
247
248        length = new GenePropsOp_Old(0.33, 2.0, GeneProps::standard_values.length, 0.3);
249        weight = new GenePropsOp_Old(0.5, 2.0, GeneProps::standard_values.weight, 0.3);
250        friction = new GenePropsOp_Old(0, 4.0, GeneProps::standard_values.friction, 0.2);
251        curvedness = new GenePropsOp_Old(-2, 2, GeneProps::standard_values.curvedness, 0.25);
252        twist = new GenePropsOp_Old(-M_PI_2, M_PI_2, GeneProps::standard_values.twist, 0.3);
253        energy = new GenePropsOp_Old(0, 10, GeneProps::standard_values.energy, 0.1);
254
255        assimilation = new GenePropsOp_Old(0, 1, GeneProps::standard_values.assimilation, 0.8, 0.4);
256        ingestion = new GenePropsOp_Old(0, 1, GeneProps::standard_values.ingestion, 0.8, 0.4);
257        stamina = new GenePropsOp_Old(0, 1, GeneProps::standard_values.stamina, 0.8, 0.4);
258        muscle_power = new GenePropsOp_Old(0, 1, GeneProps::standard_values.muscle_power, 0.8, 0.4);
259
260        cred = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cred, 0.25);
261        cgreen = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cgreen, 0.25);
262        cblue = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cblue, 0.25);
263}
264
265GenePropsOps_New05::GenePropsOps_New05()
266{
267        use_normalizebiol4 = false;
268        auto fields = { length,curvedness,weight,friction,muscle_power,assimilation,stamina,ingestion,twist,energy,cred,cgreen,cblue };
269        for (auto x : fields)
270        {
271                auto xx = dynamic_cast<GenePropsOp_Old*>(x);
272                if (xx)
273                        xx->change = xx->revchange = 0.5;
274        }
275}
276
277GenePropsOps_Exponential::GenePropsOps_Exponential()
278{
279        length = new GenePropsOp_Exponential(0.33, 2.0, GeneProps::standard_values.length);
280        weight = new GenePropsOp_Exponential(0.5, 2.0, GeneProps::standard_values.weight);
281        friction = new GenePropsOp_Exponential(0, 4.0, GeneProps::standard_values.friction);
282        curvedness = new GenePropsOp_Exponential(-2, 2, GeneProps::standard_values.curvedness);
283        twist = new GenePropsOp_Exponential(-M_PI_2, M_PI_2, GeneProps::standard_values.twist);
284        energy = new GenePropsOp_Exponential(0, 10, GeneProps::standard_values.energy);
285
286        assimilation = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.assimilation);
287        ingestion = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.ingestion);
288        stamina = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.stamina);
289        muscle_power = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.muscle_power);
290
291        cred = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cred);
292        cgreen = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cgreen);
293        cblue = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cblue);
294}
295
296
297GenePropsOps* GeneProps::standard_ops = NULL;
298GenePropsOps* GeneProps::getStandardOps()
299{
300        if (!standard_ops)
301                standard_ops = new GenePropsOps_New05();
302        return standard_ops;
303}
Note: See TracBrowser for help on using the repository browser.