⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tierra.c

📁 地球模拟器
💻 C
字号:
/* tierra.c   9-9-92  main module of Tierra Simulator *//* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */#ifndef lintstatic char     sccsid[] = "@(#)tierra.c        1.5 7/21/92";#endif#include "license.h"#include "tierra.h"#include "declare.h"#include "soup_in.h"#include <sys/types.h>#include <fcntl.h>#ifdef unix#include <unistd.h>#endif#ifdef MEM_CHK#include <memcheck.h>#endif#ifdef ALCOMM#include "tmonitor.h" #include "trequest.h"#include <mlayer.h>#include <alcomm.h>#define                                                 _MFnCount       2static MtDefaultRoutines        _message_fns[] = {  { TrtPauseSim,        TSimRuncontrol },  { TrtResumeSim,       TSimRuncontrol }};#define                                                 _QFnCount       2static MtDefaultRoutines        _query_fns[] = {  { TrtGeneralStats,    TQueryGeneralStats },  { TrtQueryOrg,        TQueryOrganism }};#define                                                 _DIFnCount      4static MtDefaultRoutines        _dfinit_fns[] = {  { TrtOrgLifeEvent,    TInitOrgLifeEvents},  { TrtIPEvent,         TMoveIP},  { 1,         TMoveD} ,  { TrtPlanEvent,       TPlan}};#endif         /*ALCOMM */I32s   FindCell;I32s   itime, mtime;Event  FindTime;int main(argc,argv)    int   argc;    char  *argv[];{   FEStartup();         #ifdef MEM_CHK    mc_startcheck(FEMemCheck); /* set memcheck=on */#endif#ifdef ALCOMM    _t_init_alcomm();#endif /* ALCOMM */    GetSoup(argc,argv);     if(argc > 2) FEMenu();    life();    WriteSoup(1);#ifdef MEM_CHKmc_endcheck();#endif    if(Log)        fclose(tfp_log);    FEExit(0);}void life() /* doles out time slices and death */{/*  while(InstExe.m < alive) */    while(Generations < alive)    {if (KEYHIT()) FEMenu();#ifdef __TURBOC__    if (GoDown)        FEError(-1000,EXIT,WRITE,      "Tierra life() memory fragmented & running low, saving system to disk");#endif /* __TURBOC__ */#ifdef ALCOMM      if ( AL_run_flag == 1 )        {   (*slicer)();            ReapCheck();        }      _t_life_bookeep();#else /* ALCOMM */        (*slicer)();        ReapCheck();#endif /* ALCOMM */    }}void TimeSlice(ce, size_slice)Pcells  ce;I32s    size_slice;{   I8s     a = 0, b = 0;    I16s    di;  /* decoded instruction */    I16s    gi;    I32s    si, ar, ci, NumAnc, value;    GList  Fp pgl;    SList  Fp Fp tsl, Fp psl;    Pcells  tce, sce;    ce->d.ib += size_slice;    for(is.ts = ce->d.ib; is.ts > 0; )    {   di = FetchDecode(ce);#ifdef EXECPROT        if (is.eins->exec && !IsInsideCell(ce,is.oip))            SetFlag(ce);        else#endif /* EXECPROT */        (*id[di].execute)(ce);        IncrementIp(ce);/*                       FOR DEBUGGING PURPOSES */        if (debug && InstExe.m >= FindTime.m && InstExe.i >= FindTime.i)        {                    a = b;        }/* */        SystemWork(ce);    }}I16s FetchDecode(ce)Pcells  ce;{   I16s    di;#if PLOIDY == 1    is.eins = &soup[ce->c.ip];#else /* PLOIDY > 1 */    is.eins = &soup[ce->c.ip][ce->d.tr];#endif /* PLOIDY > 1 */    di = is.eins->inst;    is.oip = ce->c.ip;    (*id[di].parse)(ce);#ifdef MICROif( MC_step  > -1L) Micro_Spy(ce);#endif    return di;}void IncrementIp(ce)Pcells  ce;{   ce->c.ip += is.iip;    ce->c.ip = ad(ce->c.ip);    ce->d.ib -= is.dib;    is.ts -= is.dib;    if (WatchExe)        GenExExe(ce, is.oip);}void SystemWork(ce)Pcells  ce;{   ce->d.inst += is.dib;    if(ce->c.fl)    {   ce->d.flags++;        if(!ce->d.dm)            UpRprIf(ce);    }    CountMutRate++;    if(CountMutRate >= RateMut && RateMut)    {   mutate();        TotMut++;        CountMutRate = tlrand() % RateMut;    }    if(isolate) extract(&cells[extr.a][extr.i]);    InstExe.i++;    if(InstExe.i > 1000000L)    {   InstExe.i %= 1000000L; InstExe.m++;        if(DropDead && (InstExe.m > LastDiv.m + DropDead))        {   FEError(-1001,EXIT,WRITE,                "Tierra SystemWork() soup has died, saving system to disk");        }        if(!(InstExe.m % SaveFreq)) WriteSoup(0);        plan();    }}void mutate(){   I32s  i;    i = tlrand() % SoupSize;#if PLOIDY == 1    mut_site(soup + i, tcrand());#else /* PLOIDY > 1 */    mut_site(soup + i, tcrand() % PLOIDY);#endif /* PLOIDY > 1 */    MutBookeep(i);}void mut_site(s, t)HpInst  s;I32s     t;{   #if PLOIDY == 1s[0].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); #else /* PLOIDY > 1 */s[0][t].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); #endif /* PLOIDY > 1 */}void ReapCheck() /* kill some cells if necessary */{   I32s  i, t, dtime;    Event  result;    if(DistFreq < -.00001 || !reaped || (!DistNext.m && !DistNext.i))        return;    dtime = SubEvent(&InstExe, &DistNext, &result);    if(dtime > 0)    {   Disturb = InstExe;        DistNext.m = DistNext.i = 0L;        t = (I32s) (DistProp * (float) NumCells);        if(t == NumCells)            t--;        for(i = 0; i < t; i++)            reaper(0,-1);    }}void reaper(ex, sad)I32s  ex;  /* is a creature executing now ? */I32s  sad; /* suggested address for reaping */{   Pcells  ce; /* cell to be reaped */    Pcells  nc; /* daughter of cell to be reaped */    Event   result;    I32s    reap_range,i, j, ll, ul, goon, rtime, found = 0;    if (MalReapTol && (sad >= 0 && sad < SoupSize))    {   ce = TopReap; i = 1; goon = 1;        ll = sad - MalLimit;        ul = sad + MalLimit + 1;        while (goon)        {   goon = 0;            if (ex && ce == ThisSlice)                goon = 1;            if (ce->md.s)            {   if ((((ce->mm.p + ce->mm.s) < ll) || (ce->mm.p > ul))                    && (((ce->md.p + ce->md.s) < ll) || (ce->md.p > ul)))                goon = 1;            }            else            {   if (((ce->mm.p + ce->mm.s) < ll)                    || (ce->mm.p > ul))                goon = 1;            }            if (goon)            {   ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];                i++;            }            if (i > NumCells || (!ce)                || ((ce->q.this.a == 0) && (ce->q.this.i < 2)))                 break;            if (!goon)            {   found = 1;                break;            }        }    }    if (!found)    {   reap_range =  ReapRndProp * NumCells;        if(reap_range < 2)            ce = TopReap;        else        /* pick rnd cell in top reap_range */        {   j = tlrand() % reap_range;            for(ce = TopReap, i = 0; i < j; i++)            {   ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];#ifdef ERROR                if ((!ce) || ((ce->q.this.a ==0) && (ce->q.this.i < 2)))         FEError(-1002,EXIT,WRITE,"Tierra reaper() error, queues corrupted!");#endif            }        }    }    if(ex && ce == ThisSlice)    {   if(ce == TopReap)            ce = &cells[ce->q.n_reap.a][ce->q.n_reap.i];        else            ce = &cells[ce->q.p_reap.a][ce->q.p_reap.i];    }    if(ex && DistFreq > -.00001 && !DistNext.m && !DistNext.i)    {   rtime = SubEvent(&InstExe, &Disturb, &result);        rtime = (I32s) (DistFreq * (float) rtime);        DistNext = Disturb = InstExe;        DistNext.m += rtime / 1000000L;        DistNext.i += rtime % 1000000L;        DistNext.m += DistNext.i / 1000000L;        DistNext.i %= 1000000L;    }    if(NumCells == 1)    {   FEError(-1003,EXIT,WRITE,            "Tierra reaper() error 0, attempt to reap last creature");    }    /* DAN old ce = TopReap; l_top = TopReap; */#ifdef ERROR    if(!ce->ld || !NumCells || (!ce->mm.s && !ce->md.s))    {   FEError(-1004,EXIT,WRITE,            "Tierra reaper() error 1, attempt to reap non-existant cell");    }#endif    if(ce->mm.s)    {#ifdef ERROR        if(ce->mm.p < 0 || ce->mm.p >= SoupSize)        {   FEError(-1005,EXIT,WRITE,   "Tierra reaper() error 2: attemp to deallocate mother memory not in soup");        }#endif        chmode(ce, ce->mm.p,ce->mm.s,MemModeFree);              /* DAN should check return */        MemDealloc(ce->mm.p,ce->mm.s);    }    if(ce->md.s && (ce->md.p > -1))    {#ifdef ERROR        if(ce->md.p < 0 || ce->md.p >= SoupSize)        {   FEError(-1006,EXIT,WRITE,"Tierra reaper() error 3: attemp to deallocate daughter memory not in soup");        }#endif        if(ce->d.ne.a != ce->q.this.a || ce->d.ne.i != ce->q.this.i)            /* cleanup daughter cpu */        {   nc = &cells[ce->d.ne.a][ce->d.ne.i];            if(nc->d.is) /* cleanup daughter instruction pointer */                RmvFrmSlicer(nc);            NumCells--;            InitCell(nc->q.this.a, nc->q.this.i, nc);        }        chmode(ce, ce->md.p,ce->md.s,MemModeFree);                /* DAN should check return */        MemDealloc(ce->md.p,ce->md.s);    }    if(ce->md.s && ce->md.p == -1)    {    if (ce->d.genome)         {   tfree(ce->d.genome);             ce->d.genome = soup + ce->mm.p;         }    }    RmvFrmSlicer(ce);    RmvFrmReaper(ce);    ReapBookeep(ce);/*  InitCell(ci); done in ReapBookeep(ci); */}I32s SubEvent(event1, event2, result) /* subtract e2 from e1 */Event  *event1, *event2, *result;{   result->m =  event1->m - event2->m;    result->m += (event1->i - event2->i) / 1000000L;    result->i =  (event1->i - event2->i) % 1000000L;    if(result->m <= 0)        return result->i + (result->m * 1000000L);    if(result->i < 0)    {   --result->m;        result->i += 1000000L;    }    return result->i + (result->m * 1000000L);}/* --------------------------------------------------------------------- */#ifdef ALCOMMvoid _t_init_alcomm(){  MtStatus      iRet;  AL_run_flag = 1;    VPORT = 7001;    if (( iRet = MInitialise( 0, 0,                              _message_fns, _MFnCount,                              _query_fns, _QFnCount,                              M_NoFns, 0,                              _dfinit_fns, _DIFnCount )        ) != MsOK )      {FEError(-1007,NOEXIT,NOWRITE,          "Tierra _t_init_alcomm() main MInitialise error (%d)\n", iRet );}    for(VPORT=7001;VPORT < 8000;VPORT++)       {       if (( iRet = MOpenPublicPort( VPORT )) != MsOK )         {FEError(-1008,NOEXIT,NOWRITE,             "Tierra _t_init_alcom() main MOpenPublicPort error (%d) on # %d",             iRet, VPORT);         }       else break;       }}void _t_life_bookeep(){I32s         acount=50;MtStatus     iRet;      if ( AL_run_flag == 1 )        {         if ( MIsDFEnabled( TrtIPEvent ) )              {              TMoveIP( ThisSlice->mm.p,ThisSlice->c.ip);              }        }        else        {        if(acount++ > 30)          {          FEPrintf(0,0,1,"ALMOND: holding\n");          acount = 0;          }        sleep( 1 );        }      if (( iRet = MServiceRequests( M_NoWait )) != MsOK )      {sprintf(mes[0], "life MServiceRequests error (%d)\n", iRet );      FEMessage(1,mes);}}#endif /* ALCOMM *//* ----------------------- END OF TIERRA.C ----------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -