Changeset 1242 for cpp/frams/genetics


Ignore:
Timestamp:
05/18/23 14:19:34 (20 months ago)
Author:
Maciej Komosinski
Message:

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

Location:
cpp/frams/genetics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/geneprops.cpp

    r1130 r1242  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    4949}
    5050
    51 int GeneProps::executeModifier(char modif)
     51int GeneProps::executeModifier_Legacy(char modif)
    5252{
    5353        switch (modif)
    5454        {
    5555#ifdef v1f1COMPATIBLE
    56         case 'L': length += (3.0 - length)*0.3;
     56        case 'L': length += (3.0 - length) * 0.3;
    5757                length = std::min(length, Model::getMaxJoint().d.x); break;
    5858#else
    59         case 'L': length += (2.0 - length)*0.3; //2.0 is currently Model::getMaxJoint().d.x so min() does not limit the range
     59        case 'L': length += (2.0 - length) * 0.3; //2.0 is currently Model::getMaxJoint().d.x so min() does not limit the range
    6060                length = std::min(length, Model::getMaxJoint().d.x); break;
    6161#endif
    62         case 'l': length += (0.33 - length)*0.3;
     62        case 'l': length += (0.33 - length) * 0.3;
    6363                length = std::max(length, Model::getMinJoint().d.x); break;
    6464
    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;
     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;
    6969        case 'C': curvedness += (2.0 - curvedness) * 0.25; break;
    7070        case 'c': curvedness += (-2.0 - curvedness) * 0.25; break;
    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;
    75 
    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;
    84 
    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;
     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;
     75
     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;
     84
     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;
    9191
    9292        default: return -1;
     
    9595}
    9696
     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
    97138void GeneProps::propagateAlong(bool use_f1_muscle_reset_range)
    98139{
    99         length = 0.5*length + 0.5 * standard_values.length;
     140        length = 0.5 * length + 0.5 * standard_values.length;
    100141        weight += (standard_values.weight - weight) * 0.5;
    101142        friction = 0.8 * friction + 0.2 * standard_values.friction;
     
    115156        }
    116157}
     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}
  • cpp/frams/genetics/geneprops.h

    r1039 r1242  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    1919
    2020
     21class GenePropsOp
     22{
     23public:
     24        virtual ~GenePropsOp() {}
     25        virtual double increase(double value) const = 0;
     26        virtual double decrease(double value) const = 0;
     27        void apply(double &value, char modif) const;
     28};
    2129
     30class GenePropsOp_Old : public GenePropsOp
     31{
     32        double minvalue, maxvalue, defvalue, change, revchange;
     33public:
     34        GenePropsOp_Old(double minvalue, double maxvalue, double defvalue, double change, double revchange = -1);
     35        double increase(double value) const;
     36        double decrease(double value) const;
     37        friend class GenePropsOps_New05;
     38};
     39
     40class GenePropsOp_NormalizedAndScaled : public GenePropsOp
     41{
     42        GenePropsOp_Old normalized;
     43public:
     44        GenePropsOp_NormalizedAndScaled(double change) :normalized(-1, 1, 0, change) {}
     45        virtual double scale(double value) const { return value; }
     46        virtual double scaleInv(double value) const { return value; }
     47        double increase(double value) const { return scale(normalized.increase(scaleInv(value))); }
     48        double decrease(double value) const { return scale(normalized.decrease(scaleInv(value))); }
     49};
     50
     51class GenePropsOp_Exponential : public GenePropsOp_NormalizedAndScaled
     52{
     53        double a, b, c;
     54        double log_a;
     55        bool linear;
     56public:
     57        GenePropsOp_Exponential(double minvalue, double maxvalue, double defvalue, double change = 0.5);
     58        double scale(double) const;
     59        double scaleInv(double) const;
     60};
     61
     62class GenePropsOps
     63{
     64public:
     65        ~GenePropsOps();
     66
     67        GenePropsOp* length;
     68        GenePropsOp* curvedness;
     69        GenePropsOp* weight;
     70        GenePropsOp* friction;
     71        GenePropsOp* muscle_power;
     72        GenePropsOp* assimilation;
     73        GenePropsOp* stamina;
     74        GenePropsOp* ingestion;
     75        GenePropsOp* twist;
     76        GenePropsOp* energy;
     77        GenePropsOp* cred, *cgreen, *cblue;
     78        bool use_normalizebiol4;
     79};
     80
     81class GenePropsOps_Old : public GenePropsOps
     82{
     83public:
     84        GenePropsOps_Old();
     85};
     86
     87class GenePropsOps_New05 : public GenePropsOps_Old
     88{
     89public:
     90        GenePropsOps_New05();
     91};
     92
     93class GenePropsOps_Exponential : public GenePropsOps
     94{
     95public:
     96        GenePropsOps_Exponential();
     97};
    2298
    2399/**
     
    29105 * parents (prop) modified with the prop.propagateAlong() method.
    30106 * "Biological" properties (assimilation, stamina, muscle strength and
    31  * ingestion) should be normalized after modification with normalizeBiol4().
     107 * ingestion) can be normalized after modification with normalizeBiol4().
    32108 */
    33109struct GeneProps
     
    55131
    56132        static GeneProps standard_values;
     133        static GenePropsOps* standard_ops;
     134        static GenePropsOps* getStandardOps();
    57135
    58136        /**
     
    62140
    63141        /**
    64          * Normalizes biological properties (muscle_power,
    65          * assimilation, stamina, and ingestion). This method is called in
    66          * executeModifier() when any of the biological properties is modified. All values
    67          * of those properties sum up to 1.
     142         * Normalizes biological properties (muscle_power, assimilation, stamina, and ingestion).
     143         * This method is called in executeModifier() when any of the biological properties is modified
     144         * and \a use_normalizebiol4 is true. All values of those properties sum up to 1.
    68145         */
    69146        void normalizeBiol4();
     
    75152         * @return 0 if the provided character was property modifier, -1 otherwise
    76153         */
    77         int executeModifier(char modif);
     154        int executeModifier(char modif, GenePropsOps* ops = NULL);
     155        int executeModifier_Legacy(char modif);
    78156
    79157        /**
Note: See TracChangeset for help on using the changeset viewer.