Ignore:
Timestamp:
04/28/23 23:44:31 (2 years ago)
Author:
Maciej Komosinski
Message:

Fixed a bug where an f4_Node tree that resulted from an f4 genotype that was not properly/completely parsed due to some error would still be used to try growing an organism

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/f4/f4_general.cpp

    r1227 r1228  
    3333}
    3434
    35 int scanrec(const char* s, size_t slen, char stopchar)
    36 {
    37         size_t i = 0;
     35int scanRecur(const char* s, int slen, char stopchar)
     36{
     37        int i = 0;
    3838        //DB( printf("    scan('%s', '%c')\n", s, stopchar); )
    3939        while (1)
    4040        {
    41                 if (i >= slen)  // ran out the string, should never happen with correct string
     41                if (i >= slen)  // ran out the string, should never happen with a correct string
    4242                        return 1;
    4343                if (stopchar == s[i])  // bumped into stopchar
     
    4747                        if (s[i] == '(')
    4848                        {
    49                                 i += 2 + scanrec(s + i + 1, slen - i - 1, ')');
     49                                i += 2 + scanRecur(s + i + 1, slen - i - 1, ')');
    5050                                continue;
    5151                        }
    5252                        if (s[i] == '<')
    5353                        {
    54                                 i += 2 + scanrec(s + i + 1, slen - i - 1, '>');
     54                                i += 2 + scanRecur(s + i + 1, slen - i - 1, '>');
    5555                                continue;
    5656                        }
    5757                        if (s[i] == '#')
    5858                        {
    59                                 i += 2 + scanrec(s + i + 1, slen - i - 1, '>');
     59                                i += 2 + scanRecur(s + i + 1, slen - i - 1, '>');
    6060                                continue;
    6161                        }
    6262                }
    63                 // s[i] a non-special character
     63                // s[i] is a non-special character
    6464                i++;
    6565        }
    66         return int(i);
     66        return i;
    6767}
    6868
     
    703703f4_Cells::f4_Cells(SString & genome, int nrepair)
    704704{
    705         int res;
    706705        repair = nrepair;
    707706        errorcode = GENOPER_OK;
     
    715714        // transform geno from string to nodes
    716715        f4rootnode = new f4_Node();
    717         res = f4_processrec(genome.c_str(), 0, f4rootnode);
    718         if ((res < 0) || (1 != f4rootnode->childCount()))
     716        int res = f4_processRecur(genome.c_str(), 0, f4rootnode);
     717        if (res || (f4rootnode->childCount() != 1))
    719718        {
    720719                errorcode = GENOPER_OPFAIL;
     
    833832                switch (c->type)
    834833                {
    835                 case CELL_UNDIFF: type = "UNDIFF"; break;
     834                case CELL_UNDIFF: type = "undiff"; break;
    836835                case CELL_STICK:  type = "STICK"; break;
    837836                case CELL_NEURON: type = string("NEURON:") + c->neuclass->name.c_str(); break;
     
    12181217{
    12191218        int n = count();
    1220         // pick a random node, between 0 and n-1
     1219        // pick a random node between 0 and n-1
    12211220        return ordNode(rndUint(n));
    12221221}
     
    13411340// scan genotype string and build tree
    13421341// return >1 for error (errorpos)
    1343 int f4_processrec(const char* genot, unsigned pos0, f4_Node *parent)
    1344 {
    1345         int i, res;
    1346         unsigned gpos, oldpos;
    1347         f4_Node *node1, *par;
    1348         unsigned beginindex;
     1342int f4_processRecur(const char* genot, unsigned pos0, f4_Node *parent)
     1343{
     1344        unsigned int gpos;
     1345        f4_Node *par;
    13491346
    13501347        gpos = pos0;
     
    13591356                {
    13601357                        // find out genotype start for child
    1361                         int j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>');
    1362 
    1363                         node1 = new f4_Node("<", par, gpos);
    1364                         par = node1;
    1365                         res = f4_processrec(genot, gpos + 1, par);
     1358                        int stopchar_offset = scanRecur(genot + gpos + 1, (int)strlen(genot + gpos + 1), '>');
     1359
     1360                        f4_Node *node = new f4_Node("<", par, gpos);
     1361                        par = node;
     1362                        int res = f4_processRecur(genot, gpos + 1, par);
    13661363                        if (res) return res;
    1367                         if (gpos + j + 2 < strlen(genot))
    1368                         {
    1369                                 res = f4_processrec(genot, gpos + j + 2, par);
     1364                        if (gpos + stopchar_offset + 2 < strlen(genot))
     1365                        {
     1366                                res = f4_processRecur(genot, gpos + stopchar_offset + 2, par);
    13701367                                if (res) return res;
    13711368                        }
    13721369                        else // ran out
    13731370                        {
    1374                                 node1 = new f4_Node(">", par, int(strlen(genot)) - 1);
    1375                                 par = node1;
     1371                                node = new f4_Node(">", par, int(strlen(genot)) - 1);
     1372                                par = node;
    13761373                        }
    13771374                        gpos++;
     
    13801377                case '>':
    13811378                {
    1382                         node1 = new f4_Node(">", par, gpos);
    1383                         par = node1;
     1379                        f4_Node *node = new f4_Node(">", par, gpos);
     1380                        par = node;
    13841381                        gpos = (unsigned int)strlen(genot);
    13851382                        return 0;  // OK
     
    13901387                        ExtValue val;
    13911388                        const char* end = val.parseNumber(genot + gpos + 1, ExtPType::TInt);
    1392                         if (end == NULL) i = 1;
    1393                         else i = val.getInt();
     1389                        int reps = (end == NULL) ? 1 : val.getInt();
    13941390                        // find out genotype start for continuation
    1395                         int j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>');
     1391                        int stopchar_offset = scanRecur(genot + gpos + 1, (int)strlen(genot + gpos + 1), '>');
    13961392                        // skip number
    1397                         oldpos = gpos;
     1393                        unsigned int oldpos = gpos;
    13981394                        gpos += end - (genot + gpos);
    13991395                        //gpos++;
    14001396                        //while ((genot[gpos] >= '0') && (genot[gpos] <= '9')) gpos++;node1 = new f4_Node("#", par, oldpos);
    1401                         node1 = new f4_Node("#", par, oldpos);
    1402                         node1->reps = i;
    1403                         par = node1;
    1404                         res = f4_processrec(genot, gpos, node1);
     1397                        f4_Node *node = new f4_Node("#", par, oldpos);
     1398                        node->reps = reps;
     1399                        par = node;
     1400                        int res = f4_processRecur(genot, gpos, node);
    14051401                        if (res) return res;
    1406                         if (oldpos + j + 2 < strlen(genot))
    1407                         {
    1408                                 res = f4_processrec(genot, oldpos + j + 2, node1);
     1402                        if (oldpos + stopchar_offset + 2 < strlen(genot))
     1403                        {
     1404                                res = f4_processRecur(genot, oldpos + stopchar_offset + 2, node);
    14091405                                if (res) return res;
    14101406                        }
    14111407                        else // ran out
    14121408                        {
    1413                                 node1 = new f4_Node(">", par, int(strlen(genot)) - 1);
     1409                                node = new f4_Node(">", par, int(strlen(genot)) - 1);
    14141410                        }
    14151411                        return 0;  // OK
     
    14301426                                return gpos + 1; //error
    14311427                        gpos += 2; //skipping "N:"
    1432                         beginindex = gpos;
    1433                         char* end = (char*)genot + beginindex;
     1428                        unsigned int begin_index = gpos;
     1429                        char* end = (char*)genot + begin_index;
    14341430                        NeuroClass *neuclass = GenoOperators::parseNeuroClass(end, ModelEnum::SHAPETYPE_BALL_AND_STICK);
    14351431                        if (neuclass == NULL)
    14361432                                return gpos + 1; //error
    1437                         gpos += end - genot - beginindex;
    1438                         string neutype = string(genot + beginindex, genot + gpos);
    1439                         node1 = new f4_Node(neutype, par, forgenorange);
    1440                         node1->neuclass = neuclass;
    1441                         par = node1;
     1433                        gpos += end - genot - begin_index;
     1434                        string neutype = string(genot + begin_index, genot + gpos);
     1435                        f4_Node *node = new f4_Node(neutype, par, forgenorange);
     1436                        node->neuclass = neuclass;
     1437                        par = node;
    14421438                        // if it continues with a colon that determines a neuron parameter (e.g. N:N:+=: ), then let the switch case for colon handle this
    14431439                        break;
     
    14591455                                return gpos + 1 + 1; //error
    14601456                        }
    1461                         node1 = new f4_Node(":", par, gpos);
    1462                         node1->prop_symbol = prop_symbol;
    1463                         node1->prop_increase = prop_dir == '+' ? true : false; // + or -
    1464                         par = node1;
    1465                         int chars = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ':');
    1466                         gpos += chars + 2;
     1457                        f4_Node *node = new f4_Node(":", par, gpos);
     1458                        node->prop_symbol = prop_symbol;
     1459                        node->prop_increase = prop_dir == '+' ? true : false; // + or -
     1460                        par = node;
     1461                        int stopchar_offset = scanRecur(genot + gpos + 1, (int)strlen(genot + gpos + 1), ':');
     1462                        gpos += stopchar_offset + 2;
    14671463                        break;
    14681464                }
     
    14751471                                return gpos + 1; //error
    14761472
    1477                         node1 = new f4_Node("[", par, gpos);
    1478                         node1->conn_from = relfrom;
    1479                         node1->conn_weight = weight;
    1480                         par = node1;
    1481                         int j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ']');
    1482                         gpos += j + 2;
     1473                        f4_Node *node = new f4_Node("[", par, gpos);
     1474                        node->conn_from = relfrom;
     1475                        node->conn_weight = weight;
     1476                        par = node;
     1477                        int stopchar_offset = scanRecur(genot + gpos + 1, (int)strlen(genot + gpos + 1), ']');
     1478                        gpos += stopchar_offset + 2;
    14831479                        break;
    14841480                }
     
    14861482                {
    14871483                        //printf("any regular character '%c'\n", genot[gpos]);
    1488                         node1 = new f4_Node(genot[gpos], par, gpos);
    1489                         par = node1;
     1484                        f4_Node *node = new f4_Node(genot[gpos], par, gpos);
     1485                        par = node;
    14901486                        gpos++;
    14911487                        break;
     
    14991495                if (par->name != ">")
    15001496                {
    1501                         node1 = new f4_Node('>', par, int(strlen(genot)) - 1);
    1502                         par = node1;
     1497                        f4_Node *node = new f4_Node('>', par, int(strlen(genot)) - 1);
     1498                        par = node;
    15031499                }
    15041500        }
     
    15261522}
    15271523
    1528 f4_Node* f4_processtree(const char* geno)
     1524/*
     1525f4_Node* f4_processTree(const char* geno)
    15291526{
    15301527        f4_Node *root = new f4_Node();
    1531         int res = f4_processrec(geno, 0, root);
     1528        int res = f4_processRecur(geno, 0, root);
    15321529        if (res) return NULL;
    15331530        //DB( printf("test f4  "); )
     
    15451542                return root->child;
    15461543}
     1544*/
Note: See TracChangeset for help on using the changeset viewer.