home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TIERRA40.ZIP / TIERRA / TIERRA.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  11KB  |  432 lines

  1. /* tierra.c   9-9-92  main module of Tierra Simulator */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #ifndef lint
  5. static char     sccsid[] = "@(#)tierra.c        1.5 7/21/92";
  6. #endif
  7.  
  8. #include "license.h"
  9. #include "tierra.h"
  10. #include "declare.h"
  11. #include "soup_in.h"
  12. #include <sys/types.h>
  13. #include <fcntl.h>
  14. #ifdef unix
  15. #include <unistd.h>
  16. #endif
  17.  
  18. #ifdef MEM_CHK
  19. #include <memcheck.h>
  20. #endif
  21.  
  22. #ifdef ALCOMM
  23.  
  24. #include "tmonitor.h" 
  25. #include "trequest.h"
  26. #include <mlayer.h>
  27. #include <alcomm.h>
  28.  
  29. #define                                                 _MFnCount       2
  30. static MtDefaultRoutines        _message_fns[] = {
  31.   { TrtPauseSim,        TSimRuncontrol },
  32.   { TrtResumeSim,       TSimRuncontrol }
  33. };
  34.  
  35. #define                                                 _QFnCount       2
  36. static MtDefaultRoutines        _query_fns[] = {
  37.   { TrtGeneralStats,    TQueryGeneralStats },
  38.   { TrtQueryOrg,        TQueryOrganism }
  39. };
  40.  
  41. #define                                                 _DIFnCount      4
  42. static MtDefaultRoutines        _dfinit_fns[] = {
  43.   { TrtOrgLifeEvent,    TInitOrgLifeEvents},
  44.   { TrtIPEvent,         TMoveIP},
  45.   { 1,         TMoveD} ,
  46.   { TrtPlanEvent,       TPlan}
  47. };
  48.  
  49. #endif         /*ALCOMM */
  50.  
  51. I32s   FindCell;
  52. I32s   itime, mtime;
  53. Event  FindTime;
  54.  
  55. int main(argc,argv)
  56.     int   argc;
  57.     char  *argv[];
  58. {   FEStartup();         
  59.  
  60. #ifdef MEM_CHK
  61.     mc_startcheck(FEMemCheck); /* set memcheck=on */
  62. #endif
  63.  
  64. #ifdef ALCOMM
  65.     _t_init_alcomm();
  66. #endif /* ALCOMM */
  67.     GetSoup(argc,argv); 
  68.     if(argc > 2) FEMenu();
  69.     life();
  70.     WriteSoup(1);
  71.  
  72. #ifdef MEM_CHK
  73. mc_endcheck();
  74. #endif
  75.  
  76.     if(Log)
  77.         fclose(tfp_log);
  78.     FEExit(0);
  79. }
  80.  
  81. void life() /* doles out time slices and death */
  82. {
  83. /*  while(InstExe.m < alive) */
  84.     while(Generations < alive)
  85.     {
  86.  
  87. if (KEYHIT()) FEMenu();
  88. #ifdef __TURBOC__
  89.     if (GoDown)
  90.         FEError(-1000,EXIT,WRITE,
  91.       "Tierra life() memory fragmented & running low, saving system to disk");
  92. #endif /* __TURBOC__ */
  93.  
  94. #ifdef ALCOMM
  95.       if ( AL_run_flag == 1 )
  96.         {   (*slicer)();
  97.             ReapCheck();
  98.         }
  99.       _t_life_bookeep();
  100.  
  101. #else /* ALCOMM */
  102.  
  103.         (*slicer)();
  104.         ReapCheck();
  105. #endif /* ALCOMM */
  106.     }
  107. }
  108.  
  109. void TimeSlice(ce, size_slice)
  110. Pcells  ce;
  111. I32s    size_slice;
  112. {   I8s     a = 0, b = 0;
  113.     I16s    di;  /* decoded instruction */
  114.     I16s    gi;
  115.     I32s    si, ar, ci, NumAnc, value;
  116.     GList  Fp pgl;
  117.     SList  Fp Fp tsl, Fp psl;
  118.     Pcells  tce, sce;
  119.  
  120.     ce->d.ib += size_slice;
  121.     for(is.ts = ce->d.ib; is.ts > 0; )
  122.     {   di = FetchDecode(ce);
  123. #ifdef EXECPROT
  124.         if (is.eins->exec && !IsInsideCell(ce,is.oip))
  125.             SetFlag(ce);
  126.         else
  127. #endif /* EXECPROT */
  128.         (*id[di].execute)(ce);
  129.         IncrementIp(ce);
  130. /*                       FOR DEBUGGING PURPOSES */
  131.         if (debug && InstExe.m >= FindTime.m && InstExe.i >= FindTime.i)
  132.         {
  133.                     a = b;
  134.         }
  135. /* */
  136.         SystemWork(ce);
  137.     }
  138. }
  139.  
  140. I16s FetchDecode(ce)
  141. Pcells  ce;
  142. {   I16s    di;
  143.  
  144. #if PLOIDY == 1
  145.     is.eins = &soup[ce->c.ip];
  146. #else /* PLOIDY > 1 */
  147.     is.eins = &soup[ce->c.ip][ce->d.tr];
  148. #endif /* PLOIDY > 1 */
  149.     di = is.eins->inst;
  150.     is.oip = ce->c.ip;
  151.     (*id[di].parse)(ce);
  152.  
  153. #ifdef MICRO
  154. if( MC_step  > -1L) Micro_Spy(ce);
  155. #endif
  156.  
  157.     return di;
  158. }
  159.  
  160. void IncrementIp(ce)
  161. Pcells  ce;
  162. {   ce->c.ip += is.iip;
  163.     ce->c.ip = ad(ce->c.ip);
  164.     ce->d.ib -= is.dib;
  165.     is.ts -= is.dib;
  166.     if (WatchExe)
  167.         GenExExe(ce, is.oip);
  168. }
  169.  
  170. void SystemWork(ce)
  171. Pcells  ce;
  172. {   ce->d.inst += is.dib;
  173.     if(ce->c.fl)
  174.     {   ce->d.flags++;
  175.         if(!ce->d.dm)
  176.             UpRprIf(ce);
  177.     }
  178.     CountMutRate++;
  179.     if(CountMutRate >= RateMut && RateMut)
  180.     {   mutate();
  181.         TotMut++;
  182.         CountMutRate = tlrand() % RateMut;
  183.     }
  184.     if(isolate) extract(&cells[extr.a][extr.i]);
  185.     InstExe.i++;
  186.     if(InstExe.i > 1000000L)
  187.     {   InstExe.i %= 1000000L; InstExe.m++;
  188.         if(DropDead && (InstExe.m > LastDiv.m + DropDead))
  189.         {   FEError(-1001,EXIT,WRITE,
  190.                 "Tierra SystemWork() soup has died, saving system to disk");
  191.         }
  192.         if(!(InstExe.m % SaveFreq)) WriteSoup(0);
  193.         plan();
  194.     }
  195. }
  196.  
  197. void mutate()
  198. {   I32s  i;
  199.  
  200.     i = tlrand() % SoupSize;
  201. #if PLOIDY == 1
  202.     mut_site(soup + i, tcrand());
  203. #else /* PLOIDY > 1 */
  204.     mut_site(soup + i, tcrand() % PLOIDY);
  205. #endif /* PLOIDY > 1 */
  206.     MutBookeep(i);
  207. }
  208.  
  209. void mut_site(s, t)
  210. HpInst  s;
  211. I32s     t;
  212. {   
  213. #if PLOIDY == 1
  214. s[0].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); 
  215. #else /* PLOIDY > 1 */
  216. s[0][t].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); 
  217. #endif /* PLOIDY > 1 */
  218. }
  219.  
  220.  
  221. void ReapCheck() /* kill some cells if necessary */
  222. {   I32s  i, t, dtime;
  223.     Event  result;
  224.  
  225.     if(DistFreq < -.00001 || !reaped || (!DistNext.m && !DistNext.i))
  226.         return;
  227.     dtime = SubEvent(&InstExe, &DistNext, &result);
  228.     if(dtime > 0)
  229.     {   Disturb = InstExe;
  230.         DistNext.m = DistNext.i = 0L;
  231.         t = (I32s) (DistProp * (float) NumCells);
  232.         if(t == NumCells)
  233.             t--;
  234.         for(i = 0; i < t; i++)
  235.             reaper(0,-1);
  236.     }
  237. }
  238.  
  239. void reaper(ex, sad)
  240. I32s  ex;  /* is a creature executing now ? */
  241. I32s  sad; /* suggested address for reaping */
  242. {   Pcells  ce; /* cell to be reaped */
  243.     Pcells  nc; /* daughter of cell to be reaped */
  244.     Event   result;
  245.     I32s    reap_range,i, j, ll, ul, goon, rtime, found = 0;
  246.  
  247.     if (MalReapTol && (sad >= 0 && sad < SoupSize))
  248.     {   ce = TopReap; i = 1; goon = 1;
  249.         ll = sad - MalLimit;
  250.         ul = sad + MalLimit + 1;
  251.         while (goon)
  252.         {   goon = 0;
  253.             if (ex && ce == ThisSlice)
  254.                 goon = 1;
  255.             if (ce->md.s)
  256.             {   if ((((ce->mm.p + ce->mm.s) < ll) || (ce->mm.p > ul))
  257.                     && (((ce->md.p + ce->md.s) < ll) || (ce->md.p > ul)))
  258.                 goon = 1;
  259.             }
  260.             else
  261.             {   if (((ce->mm.p + ce->mm.s) < ll)
  262.                     || (ce->mm.p > ul))
  263.                 goon = 1;
  264.             }
  265.             if (goon)
  266.             {   ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];
  267.                 i++;
  268.             }
  269.             if (i > NumCells || (!ce)
  270.                 || ((ce->q.this.a == 0) && (ce->q.this.i < 2))) 
  271.                 break;
  272.             if (!goon)
  273.             {   found = 1;
  274.                 break;
  275.             }
  276.         }
  277.     }
  278.     if (!found)
  279.     {   reap_range =  ReapRndProp * NumCells;
  280.         if(reap_range < 2)
  281.             ce = TopReap;
  282.         else        /* pick rnd cell in top reap_range */
  283.         {   j = tlrand() % reap_range;
  284.             for(ce = TopReap, i = 0; i < j; i++)
  285.             {   ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];
  286. #ifdef ERROR
  287.                 if ((!ce) || ((ce->q.this.a ==0) && (ce->q.this.i < 2))) 
  288.         FEError(-1002,EXIT,WRITE,"Tierra reaper() error, queues corrupted!");
  289. #endif
  290.             }
  291.         }
  292.     }
  293.     if(ex && ce == ThisSlice)
  294.     {   if(ce == TopReap)
  295.             ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];
  296.         else
  297.             ce = &cells[ce->q.p_reap.a][ce->q.p_reap.i];
  298.     }
  299.     if(ex && DistFreq > -.00001 && !DistNext.m && !DistNext.i)
  300.     {   rtime = SubEvent(&InstExe, &Disturb, &result);
  301.         rtime = (I32s) (DistFreq * (float) rtime);
  302.         DistNext = Disturb = InstExe;
  303.         DistNext.m += rtime / 1000000L;
  304.         DistNext.i += rtime % 1000000L;
  305.         DistNext.m += DistNext.i / 1000000L;
  306.         DistNext.i %= 1000000L;
  307.     }
  308.     if(NumCells == 1)
  309.     {   FEError(-1003,EXIT,WRITE,
  310.             "Tierra reaper() error 0, attempt to reap last creature");
  311.     }
  312.     /* DAN old ce = TopReap; l_top = TopReap; */
  313. #ifdef ERROR
  314.     if(!ce->ld || !NumCells || (!ce->mm.s && !ce->md.s))
  315.     {   FEError(-1004,EXIT,WRITE,
  316.             "Tierra reaper() error 1, attempt to reap non-existant cell");
  317.     }
  318. #endif
  319.     if(ce->mm.s)
  320.     {
  321. #ifdef ERROR
  322.         if(ce->mm.p < 0 || ce->mm.p >= SoupSize)
  323.         {   FEError(-1005,EXIT,WRITE,
  324.    "Tierra reaper() error 2: attemp to deallocate mother memory not in soup");
  325.         }
  326. #endif
  327.         chmode(ce, ce->mm.p,ce->mm.s,MemModeFree);
  328.               /* DAN should check return */
  329.         MemDealloc(ce->mm.p,ce->mm.s);
  330.     }
  331.     if(ce->md.s && (ce->md.p > -1))
  332.     {
  333. #ifdef ERROR
  334.         if(ce->md.p < 0 || ce->md.p >= SoupSize)
  335.         {   FEError(-1006,EXIT,WRITE,
  336. "Tierra reaper() error 3: attemp to deallocate daughter memory not in soup");
  337.         }
  338. #endif
  339.         if(ce->d.ne.a != ce->q.this.a || ce->d.ne.i != ce->q.this.i)
  340.             /* cleanup daughter cpu */
  341.         {   nc = &cells[ce->d.ne.a][ce->d.ne.i];
  342.             if(nc->d.is) /* cleanup daughter instruction pointer */
  343.                 RmvFrmSlicer(nc);
  344.             NumCells--;
  345.             InitCell(nc->q.this.a, nc->q.this.i, nc);
  346.         }
  347.         chmode(ce, ce->md.p,ce->md.s,MemModeFree); 
  348.                /* DAN should check return */
  349.         MemDealloc(ce->md.p,ce->md.s);
  350.     }
  351.     if(ce->md.s && ce->md.p == -1)
  352.     {    if (ce->d.genome)
  353.          {   tfree(ce->d.genome);
  354.              ce->d.genome = soup + ce->mm.p;
  355.          }
  356.     }
  357.     RmvFrmSlicer(ce);
  358.     RmvFrmReaper(ce);
  359.     ReapBookeep(ce);
  360. /*  InitCell(ci); done in ReapBookeep(ci); */
  361. }
  362.  
  363. I32s SubEvent(event1, event2, result) /* subtract e2 from e1 */
  364. Event  *event1, *event2, *result;
  365. {   result->m =  event1->m - event2->m;
  366.     result->m += (event1->i - event2->i) / 1000000L;
  367.     result->i =  (event1->i - event2->i) % 1000000L;
  368.     if(result->m <= 0)
  369.         return result->i + (result->m * 1000000L);
  370.     if(result->i < 0)
  371.     {   --result->m;
  372.         result->i += 1000000L;
  373.     }
  374.     return result->i + (result->m * 1000000L);
  375. }
  376.  
  377. /* --------------------------------------------------------------------- */
  378. #ifdef ALCOMM
  379. void _t_init_alcomm()
  380. {
  381.   MtStatus      iRet;
  382.   AL_run_flag = 1;
  383.  
  384.     VPORT = 7001;
  385.     if (( iRet = MInitialise( 0, 0,
  386.                               _message_fns, _MFnCount,
  387.                               _query_fns, _QFnCount,
  388.                               M_NoFns, 0,
  389.                               _dfinit_fns, _DIFnCount )
  390.         ) != MsOK )
  391.       {FEError(-1007,NOEXIT,NOWRITE,
  392.           "Tierra _t_init_alcomm() main MInitialise error (%d)\n", iRet );}
  393.  
  394.     for(VPORT=7001;VPORT < 8000;VPORT++)
  395.        {
  396.        if (( iRet = MOpenPublicPort( VPORT )) != MsOK )
  397.          {FEError(-1008,NOEXIT,NOWRITE,
  398.              "Tierra _t_init_alcom() main MOpenPublicPort error (%d) on # %d",
  399.              iRet, VPORT);
  400.          }
  401.        else break;
  402.        }
  403. }
  404.  
  405. void _t_life_bookeep()
  406. {
  407. I32s         acount=50;
  408. MtStatus     iRet;
  409.       if ( AL_run_flag == 1 )
  410.         {
  411.          if ( MIsDFEnabled( TrtIPEvent ) )
  412.               {
  413.               TMoveIP( ThisSlice->mm.p,ThisSlice->c.ip);
  414.               }
  415.         }
  416.         else
  417.         {
  418.         if(acount++ > 30)
  419.           {
  420.           FEPrintf(0,0,1,"ALMOND: holding\n");
  421.           acount = 0;
  422.           }
  423.         sleep( 1 );
  424.         }
  425.       if (( iRet = MServiceRequests( M_NoWait )) != MsOK )
  426.       {sprintf(mes[0], "life MServiceRequests error (%d)\n", iRet );
  427.       FEMessage(1,mes);}
  428. }
  429. #endif /* ALCOMM */
  430.  
  431. /* ----------------------- END OF TIERRA.C ----------------------------- */
  432.