home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / NERVES.ZIP / 87 / UPDATE.C < prev   
Encoding:
Text File  |  1991-01-05  |  13.8 KB  |  577 lines

  1. int near update(void)
  2.  {
  3.   int i,j,k,cf;
  4.   struct neuron *np;
  5.   struct neurcalc *ncp;
  6.   struct Iint *ip;
  7.   double d,Gi,I,f,xa,ya,xf,yf,mo;
  8.   struct con *cp;
  9.   struct leg {
  10.    double bF;     /* backward force */
  11.    double fF;     /* forward force */
  12.    double lF;     /* lateral force */
  13.    } leg[6];
  14.   double bugx,bugy;
  15.   int xinc,yinc;
  16.   double mouthd[NFOOD];
  17.  
  18.   for (j=0; j<6; j++)
  19.    {
  20.     lfoot[j] = bug.foot[j]; /* save foot states */
  21.     leg[j].bF = leg[j].fF = leg[j].lF = 0;
  22.    }
  23.   for (i=0, ncp=nsc; i<nn; i++, ncp++)
  24.    ncp->Flast = ncp->F; /* save last F's for synaptic connections */
  25.   for (i=0, np=ns, ncp=nsc; i<nn; i++, np++, ncp++)
  26.    {
  27.     if (np->name[0] != 0)        /* undefined? */
  28.      {
  29.       Gi = 0;
  30.       for (cp=np->con; cp!=NULL; cp=cp->next)
  31.        { /* get currents from connected neurons */
  32.     d = (nsc+cp->s)->Flast * cp->Isr;
  33.     if (cp->ctype > 0)
  34.      {
  35.       I = (nsc+cp->c)->Flast * cp->Icr;
  36.       if (cp->ctype == 1)
  37.        d = d * (cp->U + I * 1e9);
  38.       else
  39.        if (I >= 0)
  40.         d = d * (1 + I * 1e9);
  41.        else
  42.         d = d/(1 - I * 1e9);
  43.      }
  44.     Gi += d;
  45.        }
  46.  
  47.       /* add intrinsic current */
  48.        if (np->Iint != NULL)
  49.     {
  50.      ip = np->Iint;
  51.      j = 1;
  52.      if (!ip->H && ip->type == 0)
  53.       { /* calculate tmax for V-infinity type */
  54.         d = ncp->I/np->Gmem; /* calculate Vinfinity */
  55.         if (d > ip->pL[0])
  56.          ip->tmax = ip->pL[1] - ip->pL[2]*d; /* using 31.25, change from original
  57.           */
  58.         else
  59.          ip->tmax = MAXDOUBLE;
  60.        }
  61.      if ((ncp->Vlast < np->Vt && ncp->V >= np->Vt) ||
  62.          (!ip->H && ip->tint >= ip->tmax))
  63.       { /* turn on high current */
  64.        ip->H = TRUE;
  65.        j = 0; /* restart time count */
  66.        if (ip->type == 0)
  67.         ip->tmax = ip->pH[0]; /* time is constant */
  68.        else
  69.         {
  70.          ip->tmax = (random((int)(1000.*ip->pH[1])
  71.                       - (int)(1000*ip->pH[0]) + 1)
  72.               + (int)(1000.*ip->pH[0]))/1000.;
  73.         }
  74.       }
  75.      else
  76.       if (ip->H && ip->tint >= ip->tmax)
  77.        { /* turn off high current */
  78.         ip->H = FALSE;
  79.         j = 0; /* restart time count */
  80.         if (ip->type == 1)
  81.          ip->tmax = (random((int)(1000.*ip->pL[1])
  82.                       - (int)(1000*ip->pL[0]) + 1)
  83.               + (int)(1000.*ip->pL[0]))/1000.;
  84.        }
  85.          ip->tint = (ip->tint + DT)*j; /* increment time count */
  86.  
  87.      Gi += ip->IL + ip->H*(ip->IH - ip->IL);
  88.     }
  89.  
  90.       if (i == Iextind)
  91.        Gi += Iextint * 1e-9; /* add external current */
  92.  
  93.       /* add sensory current */
  94.       Gi += sensory(np->Isens,np->name,np->pI);
  95.  
  96.       ncp->I = Gi; /* save current */
  97.  
  98.       /* calculate new V */
  99.       Gi = (Gi - ncp->V * np->Gmem)/np->Cmem;
  100.       ncp->Vlast = ncp->V;
  101.       ncp->V = ncp->V + Gi * DT;
  102.       if (fabs(ncp->V) < 1e-30) /* prevent underflow on our XT clone! */
  103.        ncp->V = 0.0;
  104.  
  105.       /* calculate F */
  106.       if (ncp->V < np->Vt)
  107.        ncp->F = 0;
  108.       else
  109.        {
  110.     d = np->Fmin - np->Gain * np->Vt;
  111.     if (ncp->V < (1 - d)/np->Gain)
  112.      ncp->F = np->Gain * ncp->V + d;
  113.     else
  114.      ncp->F = 1;
  115.        }
  116.  
  117.       /* calculate any motor output */
  118.       if (np->mtype)
  119.        {
  120.     if (np->mtype == 1 || np->mname == 0)
  121.      {
  122.       k = strlen(np->name);
  123.       if (np->name[k-2] == 'R')
  124.        j = 2;
  125.       else
  126.        j = -1;
  127.       j += np->name[k-1] - '0';
  128.      }
  129.     if (np->mtype == 1)
  130.      { /* force */
  131.       if (np->mname == 2)
  132.        leg[j].lF = np->mconst * ncp->F;
  133.       else
  134.        if (np->mname == 0)
  135.         leg[j].fF = np->mconst * ncp->F;
  136.        else
  137.         leg[j].bF = np->mconst * ncp->F;
  138.      }
  139.     else
  140.      { /* state */
  141.       if (np->mname == 0)
  142.        { /* foot */
  143.         if (ncp->F > np->mconst)
  144.          bug.foot[j] = 1;
  145.         else
  146.          bug.foot[j] = 0;
  147.        }
  148.       else
  149.        { /* mouth */
  150.         if (ncp->F > np->mconst)
  151.          bug.mouthst = 1;
  152.         else
  153.          bug.mouthst = 0;
  154.        }
  155.      }
  156.        }
  157.      }
  158.    }
  159.  
  160.   /* calculate bug position etc., info */
  161.   d = 0.;
  162.   for (j=0; j<6; j++) /* sum forces of legs that are down */
  163.    if (bug.foot[j])
  164.     d += leg[j].bF - leg[j].fF;
  165.   d = d/2.; /* calculate bug's translational velocity (adjustable!) */
  166.   f = bug.foot[0]*leg[0].lF - bug.foot[3]*leg[3].lF; /* calc turning force */
  167.   f = f/6; /* calculate bug's angular velocity (adjustable!) (5 to 6) */
  168.   bugx = bug.x - sin(bug.ang) * d * DT;
  169.   bugy = bug.y + cos(bug.ang) * d * DT;
  170.   d = bug.foot[1]*leg[1].lF - bug.foot[4]*leg[4].lF; /* calc sideways force*/
  171.   d = 2. * d;  /* (adjustable!) (20 to 2) */
  172.   bugx -= cos(bug.ang) * d * DT;
  173.   bugy -= sin(bug.ang) * d * DT;
  174.   bug.ang += f * DT;
  175.   if (bug.ang < 0)                 /* trig!!! */
  176.    bug.ang = TWOPI + bug.ang;
  177.   if (bug.ang >= TWOPI)
  178.    bug.ang = bug.ang - TWOPI;
  179.   for (j=0; j<2; j++) /* calculate antenna & cercus tip positions */
  180.    {
  181.     bug.antx[j] = bugx + antl * cos(bug.ang + antang[j]);
  182.     bug.anty[j] = bugy + antl * sin(bug.ang + antang[j]);
  183.     bug.cercx[j] = bugx + cercl * cos(bug.ang + cercang[j]);
  184.     bug.cercy[j] = bugy + cercl * sin(bug.ang + cercang[j]);
  185.    }
  186.  
  187.   /* determine antenna contact, antenna contact angle, & cercus contact */
  188.   xinc = 0;  /* "touching" variables */
  189.   yinc = 0;
  190.   antenna[0] = antenna[1] = 0;
  191.   for (j=0; j<2; j++)
  192.    {
  193.     /* check world edge contact */
  194.     if (bug.antx[j] <= MINX)
  195.      {
  196.       xinc += 1;
  197.       if (!edget[j])
  198.        {
  199.     antenna[j] = TRUE;
  200.     if (bug.ang > HALFPI && bug.ang <= PIANDAHALF) /* more trig!!! */
  201.      antcang[j] = PI - bug.ang;
  202.     else
  203.      if (bug.ang < PIANDAHALF)
  204.       antcang[j] = bug.ang;
  205.      else
  206.       antcang[j] = TWOPI - bug.ang;
  207.        }
  208.      }
  209.     else
  210.      if (bug.antx[j] >= MAXX)
  211.       {
  212.        xinc -= 1;
  213.        if (!edget[j])
  214.     {
  215.      antenna[j] = TRUE;
  216.      if (bug.ang <= PIANDAHALF && bug.ang >= HALFPI)
  217.       antcang[j] = bug.ang - PI;
  218.      else
  219.       if (bug.ang > PIANDAHALF)
  220.        antcang[j] = TWOPI - bug.ang;
  221.       else
  222.        antcang[j] = - bug.ang;
  223.     }
  224.       }
  225.     if (bug.anty[j] <= MINY)
  226.      {
  227.       yinc += 1;
  228.       if (!edget[j])
  229.        {
  230.     antenna[j] = TRUE;
  231.     if (bug.ang <= PI)
  232.      antcang[j] = bug.ang - HALFPI;
  233.     else
  234.      antcang[j] = PIANDAHALF - bug.ang;
  235.        }
  236.      }
  237.     else
  238.      if (bug.anty[j] >= MAXY)
  239.       {
  240.        yinc -= 1;
  241.        if (!edget[j])
  242.     {
  243.      antenna[j] = TRUE;
  244.      if (bug.ang <= PI )
  245.       antcang[j] = HALFPI - bug.ang;
  246.      else
  247.       antcang[j] = bug.ang - PIANDAHALF;
  248.         }
  249.       }
  250.     if (bug.cercx[j] <= MINX)
  251.      xinc += 1;
  252.     else
  253.      if (bug.cercx[j] >= MAXX)
  254.       xinc -= 1;
  255.     if (bug.cercy[j] <= MINY)
  256.      yinc += 1;
  257.     else
  258.      if (bug.cercy[j] >= MAXY)
  259.       yinc -= 1;
  260.  
  261.     /* check box edge contact */
  262.     for (i=0; i<nblock; i++)
  263.      { /* first check antenna */
  264.       if (bugx < blockx[i]
  265.       && bug.antx[j] >= blockx[i] - 1
  266.       && bug.anty[j] >= blocky[i]
  267.       && bug.anty[j] <= blocky[i] + BLOCKHEIGHT)
  268.        {
  269.     xinc -= 1;
  270.     if (!edget[j])
  271.      {
  272.       antenna[j] = TRUE;
  273.       if (bug.ang <= PIANDAHALF && bug.ang >= HALFPI)
  274.        antcang[j] = bug.ang - PI;
  275.       else
  276.        if (bug.ang > PIANDAHALF)
  277.         antcang[j] = TWOPI - bug.ang;
  278.        else
  279.         antcang[j] = - bug.ang;
  280.      }
  281.        }
  282.       else
  283.        if (bugx > blockx[i] + BLOCKWIDTH
  284.        && bug.antx[j] <= blockx[i] + BLOCKWIDTH + 1
  285.        && bug.anty[j] >= blocky[i]
  286.        && bug.anty[j] <= blocky[i] + BLOCKHEIGHT)
  287.     {
  288.      xinc += 1;
  289.      if (!edget[j])
  290.       {
  291.        antenna[j] = TRUE;
  292.        if (bug.ang > HALFPI && bug.ang <= PIANDAHALF)
  293.         antcang[j] = PI - bug.ang;
  294.        else
  295.         if (bug.ang < PIANDAHALF)
  296.          antcang[j] = bug.ang;
  297.         else
  298.          antcang[j] = TWOPI - bug.ang;
  299.       }
  300.     }
  301.       if (bugy < blocky[i]
  302.       && bug.anty[j] >= blocky[i] - 2
  303.       && bug.antx[j] >= blockx[i]
  304.       && bug.antx[j] <= blockx[i] + BLOCKWIDTH)
  305.        {
  306.     yinc -= 1;
  307.     if (!edget[j])
  308.      {
  309.       antenna[j] = TRUE;
  310.       if (bug.ang <= PI )
  311.        antcang[j] = HALFPI - bug.ang;
  312.       else
  313.        antcang[j] = bug.ang - PIANDAHALF;
  314.      }
  315.        }
  316.       else
  317.        if (bugy > blocky[i] + BLOCKHEIGHT
  318.        && bug.anty[j] <= blocky[i] + BLOCKHEIGHT + 2
  319.        && bug.antx[j] >= blockx[i]
  320.        && bug.antx[j] <= blockx[i] + BLOCKWIDTH)
  321.         {
  322.      yinc += 1;
  323.      if (!edget[j])
  324.       {
  325.        antenna[j] = TRUE;
  326.        if (bug.ang <= PI)
  327.         antcang[j] = bug.ang - HALFPI;
  328.        else
  329.         antcang[j] = PIANDAHALF - bug.ang;
  330.       }
  331.     }
  332.       /* now check cerci */
  333.       if (bugx < blockx[i]
  334.       && bug.cercx[j] >= blockx[i] - 1
  335.       && bug.cercy[j] >= blocky[i]
  336.       && bug.cercy[j] <= blocky[i] + BLOCKHEIGHT)
  337.        xinc -= 1;
  338.       else
  339.        if (bugx > blockx[i] + BLOCKWIDTH
  340.        && bug.cercx[j] <= blockx[i] + BLOCKWIDTH + 2
  341.        && bug.cercy[j] >= blocky[i]
  342.        && bug.cercy[j] <= blocky[i] + BLOCKHEIGHT)
  343.     xinc += 1;
  344.       if (bugy < blocky[i]
  345.       && bug.cercy[j] >= blocky[i] - 2
  346.       && bug.cercx[j] >= blockx[i]
  347.       && bug.cercx[j] <= blockx[i] + BLOCKWIDTH)
  348.        yinc -= 1;
  349.       else
  350.        if (bugy > blocky[i] + BLOCKHEIGHT
  351.        && bug.cercy[j] <= blocky[i] + BLOCKHEIGHT + 2
  352.        && bug.cercx[j] >= blockx[i]
  353.        && bug.cercx[j] <= blockx[i] + BLOCKWIDTH)
  354.     yinc += 1;
  355.      }
  356.    }
  357.  
  358.   if (xinc || yinc)  /* if it bounced (it didn't if touch was on both sides) */
  359.    { /* calculate bug position from old position + bounce */
  360.     bug.x += 2.5 * sgn(xinc);  /* (adjustable!) bounce */
  361.     bug.y += 2.5 * sgn(yinc);
  362.     for (j=0; j<2; j++) /* recalculate antenna & cercus tip positions */
  363.      {
  364.       bug.antx[j] = bug.x + antl * cos(bug.ang + antang[j]);
  365.       bug.anty[j] = bug.y + antl * sin(bug.ang + antang[j]);
  366.       bug.cercx[j] = bug.x + cercl * cos(bug.ang + cercang[j]);
  367.       bug.cercy[j] = bug.y + cercl * sin(bug.ang + cercang[j]);
  368.      }
  369.    }
  370.   else
  371.    {
  372.     bug.x = bugx;
  373.     bug.y = bugy;
  374.    }
  375.  
  376.   for (j=0; j<6; j++) /* calculate leg angles & foot positions */
  377.    {
  378.     if (lfoot[j] && bug.foot[j])
  379.      { /* foot stays down, stretch leg */
  380.       xa = bug.x + attl[j] * cos(bug.ang + attang[j]);
  381.       ya = bug.y + attl[j] * sin(bug.ang + attang[j]);
  382.       d = atan2(bug.footy[j] - ya,bug.footx[j] - xa);
  383.       if (d < 0.)
  384.        d = TWOPI + d;
  385.       legang[j] = d - bug.ang;
  386.       if (j < 3)
  387.        {
  388.     while (legang[j] > PI)
  389.      legang[j] = legang[j] - TWOPI;
  390.     while (legang[j] <= -PI)
  391.      legang[j] = TWOPI + legang[j];
  392.        }
  393.       else
  394.        {
  395.     while (legang[j] < 0.)
  396.      legang[j] = TWOPI + legang[j];
  397.     while (legang[j] >= TWOPI)
  398.      legang[j] = legang[j] - TWOPI;
  399.        }
  400.      }
  401.     else
  402.      { /* move foot */
  403.       if (lfoot[j] && ((j >= 3 && legang[j] < maxlegang[j]) ||
  404.               (j < 3 && legang[j] > maxlegang[j])))
  405.        legang[j] = maxlegang[j];
  406.       if (j < 3)
  407.        legang[j] += DT * (leg[j].fF + leg[j].bF) * PI/15;
  408.       else
  409.        legang[j] -= DT * (leg[j].fF + leg[j].bF) * PI/15;
  410.       bug.footx[j] = bug.x + attl[j] * cos(bug.ang + attang[j])
  411.           + legl[j] * cos(bug.ang + legang[j]);
  412.       bug.footy[j] = bug.y + attl[j] * sin(bug.ang + attang[j])
  413.           + legl[j] * sin(bug.ang + legang[j]);
  414.      }
  415.    }
  416.   energy -= .25*ENERGYPERT; /* decrement bug's energy */
  417.   if (energy <= 0.)
  418.    {
  419.     bar(430,336,454,348);
  420.     outtextxy(430,336,"RIP");
  421.     return(1); /* back to initsim */
  422.    }
  423.   odor[0] = odor[1] = mouthodor = 0.;
  424.   bug.mouthx = bug.x + hdtl * cos(bug.ang + hdtang);
  425.   bug.mouthy = bug.y + hdtl * sin(bug.ang + hdtang);
  426.   cf = 0;
  427.   mo = 0.;
  428.   for (j=0; j<nfood; j++)
  429.    { /* calculate odors for each antenna & mouth */
  430.     for (k=0; k<2; k++)
  431.      {
  432.       d = bug.antx[k] - foodx[j];
  433.       f = bug.anty[k] - foody[j];
  434.       odor[k] += .75 * foodsize[j]/(d*d + f*f); /* (adjustable!) */
  435.      }
  436.     d = bug.mouthx - foodx[j];
  437.     f = bug.mouthy - foody[j];
  438.     d = d*d + f*f;
  439.     mouthodor += foodsize[j]/d;
  440.     mouthd[j] = sqrt(d);
  441.     if (mouthodor > mo)
  442.      { /* save largest mouthodor */
  443.       mo = mouthodor;
  444.       cf = j;
  445.      }
  446.    }
  447.  
  448.   if (obug.mouthst && !bug.mouthst)  /* mouth was open, now closed */
  449.    {
  450.     energy += BITEENERGY/(2*drawmult);
  451.     foodsize[cf] -= BITEENERGY/(2*drawmult);
  452.     foodr[cf] = sqrt(foodsize[cf]/PI);
  453.    }
  454.   mouth = 0;
  455.   for (j=0; j<nfood; j++)
  456.    { /* check for mouth contact */
  457.     if (mouthd[j] <= 2*foodr[j])   /* change from original */
  458.      {
  459.       mouth = TRUE;
  460.       break;
  461.      }
  462.    }
  463.   return(0);
  464.  }
  465.  
  466. float sensory(enum senst type,char *name,float *pI)
  467.  { /* returns a sensory current */
  468.   int i,j;
  469.   float I;
  470.  
  471.   switch (type)
  472.    {
  473.     case LAF: /* leg angle forward */
  474.      i = strlen(name);
  475.      if (name[i-2] == 'R')
  476.       j = 2;
  477.      else
  478.       j = -1;
  479.      j += name[i-1] - '0';
  480.      if (j < 3)
  481.       {
  482.        if (legang[j] >= maxlegang[j])
  483.     I = *pI;
  484.        else
  485.     I = 0;
  486.       }
  487.      else
  488.       {
  489.        if (legang[j] <= maxlegang[j])
  490.     I = *pI;
  491.        else
  492.     I = 0;
  493.       }
  494.      break;
  495.  
  496.     case LAB: /* leg angle backward */
  497.      i = strlen(name);
  498.      if (name[i-2] == 'R')
  499.       j = 2;
  500.      else
  501.       j = -1;
  502.      j += name[i-1] - '0';
  503.      if (j < 3)
  504.       {
  505.        if (legang[j] <= minlegang[j])
  506.     I = *pI;
  507.        else
  508.     I = 0;
  509.       }
  510.      else
  511.       {
  512.        if (legang[j] >= minlegang[j])
  513.     I = *pI;
  514.        else
  515.     I = 0;
  516.       }
  517.      break;
  518.  
  519.     case AC: /* antenna contact */
  520.      i = strlen(name);
  521.      if (name[i-1] == 'L')
  522.       j = 0;
  523.      else
  524.       j = 1;
  525.      if (!edget[j])
  526.       {
  527.        if (antenna[j])
  528.     {
  529.      edget[j] = 100;
  530.      edgecang[j] = antcang[j];
  531.      I = *pI * edgecang[j];
  532.     }
  533.        else
  534.     I = 0;
  535.       }
  536.      else
  537.       {
  538.        edget[j]--;
  539.        I = *pI * edgecang[j];
  540.       }
  541.      break;
  542.  
  543.     case OS: /* odor strength */
  544.      i = strlen(name);
  545.      if (name[i-1] == 'L')
  546.       j = 0;
  547.      else
  548.       if (name[i-1] == 'R')
  549.        j = 1;
  550.       else
  551.        j = 2;
  552.      if (j < 2)
  553.       I = *pI * odor[j] - *(pI+1);
  554.      else
  555.       I = *pI * mouthodor - *(pI+1);
  556.      break;
  557.  
  558.     case EC: /* energy capacity */
  559.      I = *pI * energy;
  560.      break;
  561.  
  562.     case MC: /* mouth contact */
  563.      if (mouth)
  564.       I = *pI;
  565.      else
  566.       I = 0;
  567.      break;
  568.  
  569.     default:
  570.      I = 0;
  571.      break;
  572.    }
  573.  
  574.   return(I);
  575.  }
  576.  
  577.