home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NEURLNET / NERVES.ZIP / NO87 / UPDATE.C < prev   
Encoding:
Text File  |  1990-12-30  |  14.9 KB  |  595 lines

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