home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
misc
/
a154_1
/
!Tierra
/
source
/
c
/
bookeep
< prev
next >
Wrap
Text File
|
1992-08-11
|
33KB
|
958 lines
/* bookeep.c 6-7-92 bookeeping functions for the Tierra Simulator */
/* Tierra Simulator V3.13: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
#ifndef lint
static char sccsid[] = "%W% %G%";
#endif /* lint */
#include "license.h"
#include "tierra.h"
#include "extern.h"
#ifdef MEM_CHK
#include <memcheck.h>
#endif /* MEM_CHK */
void DivideBookeep(ce, nc)
Pcells ce, nc; /* ce = mother cell, nc = daughter cell */
{ GList *tgl, *tcgl;
float maxp, maxi;
I8s same = 0;
int si, gi;
LastDiv = InstExe;
if (!ce->d.fecundity && !ce->d.mut && !ce->d.flaw)
{ ce->d.d1.flags = ce->d.flags; /* record metabolic data 1st repl */
ce->d.d1.inst = ce->d.inst + 1;
ce->d.d1.mov_daught = ce->d.mov_daught;
}
ce->d.fecundity++;
nc->d.gen.size = nc->mm.s;
if (GeneBnker)
{ if (ce->mm.s == nc->mm.s && /* if cell breeds true */
IsSameGen(nc->mm.s, soup + nc->mm.p, soup + ce->mm.p))
{ if (ce->d.fecundity == 1)
nc->d.d1.BreedTrue = ce->d.d1.BreedTrue = 1;
nc->d.parent = ce->d.parent;
nc->d.gen = ce->d.gen;
nc->d.gi = ce->d.gi;
same = 1;
}
else /* if daughter is a new genotype (same = 0) */
{ nc->d.parent = ce->d.gen; /* this will assign a gen.label */
CheckGenotype(nc, 17); /* by checking .gen files */
}
tgl = sl[nc->d.gen.size]->g[nc->d.gi]; /* new cell GList */
tcgl = sl[si = ce->d.gen.size]->g[gi = ce->d.gi]; /* mother GList */
if (tcgl && (I32u) tcgl <= 4)
tcgl = sl[si]->g[gi] = gq_read(si, gi); /* mother GList */
if ((I32u) tcgl <= 4)
FEError(-100,EXIT,NOWRITE,
"Tierra DivideBookeep() mother genotype missing\n");
if (ce->d.fecundity == 1 && !ce->d.mut && !ce->d.flaw)
tcgl->d1 = ce->d.d1;
else if (ce->d.fecundity == 2 && !ce->d.mut && !ce->d.flaw)
{ tcgl->d2.inst = ce->d.inst + 1 - ce->d.d1.inst;
tcgl->d2.flags = ce->d.flags - ce->d.d1.flags;
tcgl->d2.mov_daught = ce->d.mov_daught;
tcgl->d2.BreedTrue = same;
}
si = nc->mm.s;
if (!tgl->pop)
{ NumGenotypes++;
sl[si]->num_g++;
}
tgl->pop++;
if (!sl[si]->num_c)
NumSizes++;
sl[si]->num_c++;
#if FRONTEND != STDIO
if ((IMode == SIZ_HIST)|| (IMode == SIZM_HIST) || (IMode == GEN_HIST))
query_spec_d(si,nc->d.gi);
#endif /* FRONTEND != STDIO */
/* this might be a good place to keep track of multiple parental genotypes. */
if (reaped)
{ maxp = (float) tgl->pop / (float) NumCells;
if (maxp > tgl->MaxPropPop)
{ tgl->MaxPropPop = maxp;
tgl->mpp_time = InstExe;
}
maxi = (float) tgl->pop * nc->d.gen.size / (float) SoupSize;
if (maxi > tgl->MaxPropInst)
tgl->MaxPropInst = maxi;
}
/* criteria for saving genotype to disk */
if (reaped && tgl->pop >= SavMinNum
&& ((!IsBit(tgl->bits, 0) && (tgl->MaxPropPop > SavThrPop
|| tgl->MaxPropInst > SavThrMem * .5))
|| (!IsBit(tgl->bits, 1) && (maxp > SavThrPop
|| maxi > SavThrMem * .5))))
/* if (reaped && (!IsBit(tgl->bits, 0) || !IsBit(tgl->bits, 1))
&& tgl->pop >= SavMinNum && (tgl->MaxPropPop > SavThrPop
|| tgl->MaxPropInst > SavThrMem * .5))
*/
{ if (!IsBit(tgl->bits, 0))
{ SetBit(&tgl->bits, 0, 1);
SetBit(&tgl->bits, 1, 1);
extract(nc);
}
else
{ SetBit(&tgl->bits, 1, 1);
sprintf(ExtrG, "%04ld%s @ %ld v", tgl->gen.size, tgl->gen.label,
(GeneBnker)? tgl->pop : 0L);
#if FRONTEND == STDIO
sprintf(mes[0], "extract: %s", ExtrG);
FEMessage(1,mes);
#else /* FRONTEND == STDIO */
if (Log)
fprintf(tfp_log, "ex = %s\n", ExtrG);
#endif /* FRONTEND == STDIO */
}
}
}
ce->d.mov_daught = ce->d.mut = 0;
OutDisk((I32s)'b', nc);
#if FRONTEND != STDIO
FEStats();
#endif /* FRONTEND != STDIO */
}
void ReapBookeep(ce)
Pcells ce;
{ Pgl tgl;
I32s si = ce->d.gen.size;
I16s gi = ce->d.gi;
OutDisk((I32s)'d', ce);
if (GeneBnker)
{ tgl = sl[si]->g[gi];
#ifdef ERROR
if (gi >= sl[si]->a_num)
FEError(-101,EXIT,NOWRITE,
"Tierra ReapBookeep() genotype %hd out of range\n", gi);
if ((I32u) tgl <= 4)
FEError(-102,EXIT,NOWRITE,
"Tierra ReapBookeep() genotype %hd not in genebank\n", gi);
#endif /* ERROR */
tgl->pop--; /* this is a segmentation fault waiting to happen! */
if (!tgl->pop)
{ if ((I32u) tgl > 4 && !IsBit(tgl->bits, 0))
{ if (tgl->genome)
{ tfree(tgl->genome);
tgl->genome = NULL;
}
if (tgl->gbits)
{ tfree(tgl->gbits);
tgl->gbits = NULL;
}
gq_rem(tgl);
tfree(tgl);
sl[si]->g[gi] = NULL;
}
else
SetBit(&tgl->bits, 1, 0);
NumGenotypes--;
sl[si]->num_g--;
}
sl[si]->num_c--;
if (!sl[si]->num_c)
{ NumSizes--;
#ifdef ERROR
if (sl[si]->num_g)
FEError(-103,NOEXIT,NOWRITE,
"Tierra ReapBookeep() genotypes but no individuals\n");
#endif /* ERROR */
}
#if FRONTEND != STDIO
if ((IMode == SIZ_HIST)|| (IMode == SIZM_HIST) || (IMode == GEN_HIST))
query_spec_d(si,gi);
#endif /* FRONTEND != STDIO */
}
InitCell(ce->q.this.a,ce->q.this.i,ce);
NumCells--;
reaped = 1;
}
void MutBookeep(i)
Ind i;
{
I8s md;
Pcells ce;
I32s si;
I16s gi;
Pgl tgl;
if (!GeneBnker || IsFree(i)) return;
WhichCell(i, &ce, &md);
if (md == 'm')
{ si = ce->d.gen.size;
gi = ce->d.gi;
tgl = sl[si]->g[gi];
if (IsSameGen(si, soup + ce->mm.p, tgl->genome))
return ;
#ifdef ERROR
if (gi >= sl[si]->a_num)
FEError(-104,EXIT,NOWRITE,
"Tierra MutBookeep() genotype %hd out of range\n", gi);
if ((I32u) tgl <= 4)
FEError(-105,EXIT,NOWRITE,
"Tierra MutBookeep() genotype %hd not in genebank\n", gi);
#endif /* ERROR */
tgl->pop--; /* this is a segmentation fault waiting to happen! */
if (!tgl->pop)
{ if ((I32u) tgl > 4 && !IsBit(tgl->bits, 0))
{ if (tgl->genome)
{ tfree(tgl->genome);
tgl->genome = NULL;
}
if (tgl->gbits)
{ tfree(tgl->gbits);
tgl->gbits = NULL;
}
gq_rem(tgl);
tfree(tgl);
sl[si]->g[gi] = NULL;
}
else
SetBit(&tgl->bits, 1, 0);
NumGenotypes--;
sl[si]->num_g--;
}
sl[si]->num_c--;
#if FRONTEND != STDIO
/* if (IMode == GEN_HIST) */
if ((IMode == SIZ_HIST)|| (IMode == SIZM_HIST) || (IMode == GEN_HIST))
query_spec_d(si,gi);
#endif /* FRONTEND != STDIO */
OutDisk((I32s)'d', ce);
ce->d.parent = ce->d.gen; /* assign new genotype */
ce->d.gi = -1;
strcpy(ce->d.gen.label, "---");
CheckGenotype(ce, 17); /* this will check .gen files */
gi = ce->d.gi;
tgl = sl[si]->g[gi];
#ifdef ERROR
if (gi >= sl[si]->a_num)
FEError(-106,EXIT,NOWRITE,
"Tierra MutBookeep() genotype %hd out of range\n", gi);
if ((I32u) tgl <= 4)
FEError(-107,EXIT,NOWRITE,
"Tierra MutBookeep() genotype %hd not in genebank\n", gi);
#endif /* ERROR */
if (!tgl->pop)
{ NumGenotypes++;
sl[si]->num_g++;
}
tgl->pop++;
sl[si]->num_c++;
#if FRONTEND != STDIO
/* if (IMode == GEN_HIST) */
if ((IMode == SIZ_HIST)|| (IMode == SIZM_HIST) || (IMode == GEN_HIST))
query_spec_d(si,gi);
#endif /* FRONTEND != STDIO */
OutDisk((I32s)'b', ce);
ce->d.d1.flags = ce->d.d1.mov_daught = 0L;
ce->d.fecundity = ce->d.flags = 0L;
ce->d.d1.inst = ce->d.inst = 0L;
ce->d.mut++;
}
}
void OutDisk(bd, nc)
I32s bd;
Pcells nc;
{ I32s ttime;
I8s label[4];
if (DiskOut)
{ if (FirstOutDisk)
{ FirstOutDisk = 0;
BrkupCum = 0;
BrkupCou = 1;
#ifdef IBM3090
if (BrkupSiz)
sprintf(Buff, "break.1.d");
else sprintf(Buff, "tierra.run.d");
oufr = fopen(Buff, "w");
#else /* IBM3090 */
#ifdef RISC_OS
if (BrkupSiz)
sprintf(Buff, "%sbreak_1", OutPath);
else sprintf(Buff, "%stierra_run", OutPath);
#else /*RISC_OS*/
if (BrkupSiz)
sprintf(Buff, "%sbreak.1", OutPath);
else sprintf(Buff, "%stierra.run", OutPath);
#endif /* RISC_OS */
oufr = fopen(Buff, "w");
#endif /* IBM3090 */
if (oufr == NULL)
{ FEError(-108,EXIT,NOWRITE,
"Tierra OutDisk() 1: file %s not opened, exiting\n", Buff);
}
sprintf(label, nc->d.gen.label);
#ifdef IBM3090
Ascii2Ebcdic(label);
#endif /* IBM3090 */
BrkupCum += fprintf(oufr, "%lx %c %ld", InstExe.i, (I8s) bd,
nc->d.gen.size);
if (GeneBnker)
BrkupCum += 1 + fprintf(oufr, " %s\n", label);
else BrkupCum += 1 + fprintf(oufr, "\n");
}
else
{ ttime = InstExe.i - lo.time;
if (ttime < 0)
ttime += 1000000L;
BrkupCum += fprintf(oufr, "%lx", ttime);
if (lo.bd != bd)
BrkupCum += fprintf(oufr, " %c", bd);
if (lo.size != nc->d.gen.size)
BrkupCum += fprintf(oufr, " %ld", nc->d.gen.size);
if (GeneBnker && strcmp(lo.label, nc->d.gen.label))
{ sprintf(label, nc->d.gen.label);
#ifdef IBM3090
Ascii2Ebcdic(label);
#endif /* IBM3090 */
BrkupCum += fprintf(oufr, " %s", label);
}
BrkupCum += 1 + fprintf(oufr, "\n");
if (BrkupSiz && BrkupCum > BrkupSiz * 1024L)
{ fclose(oufr);
BrkupCum = 0;
BrkupCou++;
#ifdef IBM3090
sprintf(Buff, "break.%ld.d", BrkupCou);
oufr = fopen(Buff, "w");
#else /* IBM3090 */
sprintf(Buff, "%sbreak.%ld", OutPath, BrkupCou);
oufr = fopen(Buff, "w");
#endif /* IBM3090 */
if (oufr == NULL)
{ FEError(-109,EXIT,WRITE,
"Tierra OutDisk() 2: file %s not opened, exiting\n", Buff);
}
}
}
}
else
{ if (FirstOutDisk) FirstOutDisk = 0;
else
{ ttime = InstExe.i - lo.time;
if (ttime < 0) ttime += 1000000L;
}
}
lo.bd = bd;
lo.size = nc->d.gen.size;
lo.time = InstExe.i;
strcpy(lo.label, nc->d.gen.label);
TimePop += (double) ttime *(double) NumCells;
if ((I8s) bd == 'b')
TimeBirth++;
else TimeDeath++;
}
#ifdef ERROR
void VerifyGB() /* verify genebank */
{ I32s gNumSizes = 0, cNumSizes = 0, cgNumSizes = 0;
I32s gNumGenot = 0, cNumGenot = 0, cgNumGenot = 0;
I32s gNumCells = 0, cNumCells = 0, cgNumCells = 0;
I32s cgsNumGenot = 0, ggNumGenot = 0;
I32s cgsNumCells = 0, ggNumCells = 0;
I32s tsiz_sl = 1, si, ar, ci;
I16s gi;
Pcells ce;
GList Fp pgl;
SList Fp Fp tsl, Fp psl;
/* begin cells array check */
tsl = (SList Fp Fp) tcalloc(1, sizeof(SList Fp));
for (ar = 0; ar < NumCelAr; ar++) for (ci = 0; ci < CelArSiz; ci++)
{ if (ar == 0 && ci < 2)
continue;
ce = &cells[ar][ci];
if (ce->ld)
{ cNumCells++;
si = ce->d.gen.size;
if (si >= siz_sl)
FEError(-110,EXIT,WRITE,
"Tierra VerifyGB() size %ld out of range in genebank\n", si);
psl = sl[si];
if (!psl)
FEError(-111,EXIT,WRITE,
"Tierra VerifyGB() sl[%ld] not allocated in genebank\n", si);
gi = ce->d.gi;
if (gi >= psl->a_num)
FEError(-112,EXIT,WRITE,
"Tierra VerifyGB() genome %hd out of range in genebank\n", gi);
pgl = psl->g[gi];
if ((I32u) pgl < 4)
FEError(-113,EXIT,WRITE,
"Tierra VerifyGB() gl[%hd] not allocated in genebank\n", gi);
if (!IsSameGen(si, soup + ce->mm.p, pgl->genome))
FEError(-114,EXIT,WRITE,
"Tierra VerifyGB() cell and genebank do not match\n");
if (si >= tsiz_sl)
{ tsl = (SList Fp Fp) trecalloc(tsl,
(si + 1) * sizeof(SList Fp), tsiz_sl * sizeof(SList Fp));
tsiz_sl = si + 1;
}
if (!tsl[si])
{ tsl[si] = (SList Fp) tcalloc(1, sizeof(SList));
tsl[si]->g = (GList Fp Fp) tcalloc(gi + 1, sizeof(GList Fp));
tsl[si]->a_num = gi + 1;
}
if (!tsl[si]->num_c)
{ if (tsl[si]->num_g)
FEError(-115,NOEXIT,NOWRITE,
"Tierra VerifyGB() !tsl[si]->num_c but tsl[si]->num_g\n");
cNumSizes++;
}
tsl[si]->num_c++;
if (gi >= tsl[si]->a_num)
{ tsl[si]->g = (GList Fp Fp) trecalloc(tsl[si]->g,
(gi + 1) * sizeof(GList Fp),
tsl[si]->a_num * sizeof(GList Fp));
tsl[si]->a_num = gi + 1;
}
if ((I32u) tsl[si]->g[gi] < 4)
{ tsl[si]->g[gi] = (GList Fp) tcalloc(1, sizeof(GList));
cNumGenot++;
tsl[si]->num_g++;
}
tsl[si]->g[gi]->pop++;
}
} /* check and free temporary genebank */
for (si = 0; si < tsiz_sl; si++)
{ if (tsl[si])
{ if (tsl[si]->num_c != sl[si]->num_c)
FEError(-116,NOEXIT,NOWRITE,
"Tierra VerifyGB() tsl[%ld]->num_c != sl[%ld]->num_c\n", si, si);
if (tsl[si]->num_g != sl[si]->num_g)
FEError(-117,NOEXIT,NOWRITE,
"Tierra VerifyGB() tsl[%ld]->num_g != sl[%ld]->num_g\n", si, si);
if (tsl[si]->num_c && tsl[si]->g)
{ cgNumSizes++;
cgsNumCells += tsl[si]->num_c;
cgsNumGenot += tsl[si]->num_g;
for (gi = 0; gi < tsl[si]->a_num; gi++)
{ if ((I32u) tsl[si]->g[gi] > 4)
{ if (tsl[si]->g[gi]->pop != sl[si]->g[gi]->pop)
FEError(-118,NOEXIT,NOWRITE,
"Tierra VerifyGB() tsl[%ld]->g[%hd]->pop != sl[%ld]->g[%hd]->pop\n",
si, gi, si, gi);
cgNumGenot++;
cgNumCells += tsl[si]->g[gi]->pop;
tfree(tsl[si]->g[gi]);
}
}
tfree(tsl[si]->g);
tfree(tsl[si]);
}
}
}
tfree(tsl);
if (NumCells != cNumCells || NumCells != cgNumCells ||
NumCells != cgsNumCells)
FEError(-119,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumCells cells array inconsistency\n");
if (NumGenotypes != cNumGenot || NumGenotypes != cgNumGenot ||
NumGenotypes != cgsNumGenot)
FEError(-120,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumGenot cells array inconsistency\n");
if (NumSizes != cNumSizes || NumSizes != cgNumSizes)
FEError(-121,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumSizes cells array inconsistency\n");
/* end cells array check */
/* begin genebank check */
for (si = 0; si < siz_sl; si++)
{ psl = sl[si];
if (!psl)
continue ;
if (!psl->num_c || !psl->num_g)
FEError(-122,NOEXIT,NOWRITE,
"Tierra VerifyGB() !sl[si]->num_c or !sl[si]->num_g\n");
if (sl[si]->num_c)
{ gNumSizes++;
ggNumCells += sl[si]->num_c;
}
if (sl[si]->num_g)
ggNumGenot += sl[si]->num_g;
for (gi = 0; gi < sl[si]->a_num; gi++)
{ pgl = psl->g[gi];
if ((I32u) pgl < 4 || !pgl->pop)
continue ;
gNumGenot++;
gNumCells += pgl->pop;
}
}
if (NumCells != gNumCells || NumCells != ggNumCells)
FEError(-123,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumCells genebank inconsistency\n");
if (NumGenotypes != gNumGenot || NumGenotypes != ggNumGenot)
FEError(-124,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumGenot genebank inconsistency\n");
if (NumSizes != gNumSizes)
FEError(-125,NOEXIT,NOWRITE,
"Tierra VerifyGB() NumSizes genebank inconsistency\n");
/* end genebank check */
}
#endif /* ERROR */
void GarbageCollectGB()
{ I32s i, j, maxsiz = 0, tail;
GList Fp Fp tgl, Fp pgl;
SList Fp Fp tsl;
I8s path[80];
FILE *fp;
head_t head;
indx_t *indx, gindx;
for (i = siz_sl - 1; i >= 0; i--) /* for each allocated size class */
{ if (sl[i])
{ if (sl[i]->num_c)
{ if (!maxsiz) /* find largest size class */
maxsiz = i;
tail = -1;
for (j = sl[i]->a_num - 1; j >= 0; j--)
{ if ((I32u) (pgl = sl[i]->g[j]) > 4 && !pgl->pop
&& !IsBit(pgl->bits, 0))
{ gq_rem(pgl);
if (pgl->genome)
{ tfree(pgl->genome);
pgl->genome = NULL;
}
if (pgl->gbits)
{ tfree(pgl->gbits);
pgl->gbits = NULL;
}
tfree(sl[i]->g[j]);
sl[i]->g[j] = NULL;
}
if (tail < 0 && sl[i]->g[j])
tail = j; /* skip empty geotypes at end of array */
}
if (tail < sl[i]->a_num - 1)
{ if (tail < 0) /* no genotypes in size class */
{ if (sl[i]->g)
{ tfree(sl[i]->g);
sl[i]->g = NULL;
}
if (sl[i])
{ tfree(sl[i]);
sl[i] = NULL;
}
}
else /* shorten g arrays to avoid empty tails */
{ tgl = (GList Fp Fp) trecalloc(sl[i]->g,
(tail + 1) * sizeof(GList Fp),
sl[i]->a_num * sizeof(GList Fp));
if (tgl)
sl[i]->g = tgl;
else if (sl[i]->g)
{ tfree(sl[i]->g);
sl[i]->g = NULL;
FEError(-126,EXIT,WRITE,
"Tierra GarbageCollectGB() sl[i]->g trecalloc error\n");
}
sl[i]->a_num = tail + 1;
}
}
}
else /* no creatures of this size, free sl[i] and sl[i]->g */
#ifdef RISC_OS
{ sprintf(path, "%sgen.%04ld", GenebankPath, i);
#else
{ sprintf(path, "%s%04ld.gen", GenebankPath, i);
#endif
fp = open_ar(path, i, GFormat, -1);
head = read_head(fp);
#ifdef __TURBOC__
indx = &gindx;
#else /* __TURBOC__ */
indx = read_indx(fp, &head);
#endif /* __TURBOC__ */
for (j = sl[i]->a_num - 1; j >= 0; j--)
if ((I32u) (pgl = sl[i]->g[j]) > 4)
{ if (pgl->pop)
FEError(-127,NOEXIT,NOWRITE,
"Tierra GarbageCollectGB() pgl->pop not zero, can't free\n");
if (IsBit(pgl->bits, 0)) /* save genome to disk */
add_gen(fp, &head, &indx, pgl);
if (pgl->genome)
{ tfree(pgl->genome);
pgl->genome = NULL;
}
if (pgl->gbits)
{ tfree(pgl->gbits);
pgl->gbits = NULL;
}
gq_rem(pgl);
tfree(sl[i]->g[j]);
sl[i]->g[j] = NULL;
}
fclose(fp);
if (!head.n)
unlink(path);
#ifndef __TURBOC__
if (indx)
{ thfree(indx);
indx = NULL;
}
#endif /* __TURBOC__ */
if (sl[i]->g)
{ tfree(sl[i]->g);
sl[i]->g = NULL;
}
if (sl[i])
{ tfree(sl[i]);
sl[i] = NULL;
}
}
}
}
if (maxsiz < siz_sl - 1)
{ tsl = (SList Fp Fp) trecalloc(sl, (maxsiz + 1) * sizeof(SList Fp),
siz_sl * sizeof(SList Fp));
if (tsl)
sl = tsl;
else if (sl)
{ tfree(sl);
sl = NULL;
FEError(-128,EXIT,WRITE, "Tierra GarbageCollectGB() sl trecalloc error\n");
}
siz_sl = maxsiz + 1;
} /* end garbage collect for genebank */
}
void plan()
{ I32s i, j, n = 0, indiv_gen_time, pop_gen_time;
I32s MaxPop = 0, MaxMem = 0, pop = 0, mem = 0, ar, ci;
Genotype MaxGenPop, MaxGenMem;
double prob_of_hit;
Pcells ce;
I8s *chk;
Pcells Fp tcells;
#ifdef MEM_PROF
I32s SizSoup, SizCells, SizFreeMem, SizSl, SizSli = 0;
I32s SizGl = 0, SizGli = 0, SizGen = 0;
#endif /* MEM_PROF */
if (GeneBnker && reaped)
{
GarbageCollectGB();
#ifdef ERROR
VerifyGB();
#endif /* ERROR */
}
/* begin calculate averages */
AverageSize = 0;
chk = tcalloc(NumCelAr, sizeof(I8s));
for (ar = 0; ar < NumCelAr; ar++) for (ci = 0; ci < CelArSiz; ci++)
{ if (ar == 0 && ci < 2)
continue;
ce = &cells[ar][ci];
if (ce->ld)
{ n++; chk[ar] = 1;
AverageSize += ce->d.gen.size;
if (GeneBnker && InstExe.m)
{ pop = sl[ce->d.gen.size]->g[ce->d.gi]->pop;
mem = pop * ce->d.gen.size;
if (pop > MaxPop)
{ MaxPop = pop;
MaxGenPop = ce->d.gen;
}
if (mem > MaxMem)
{ MaxMem = mem;
MaxGenMem = ce->d.gen;
}
}
}
} /* end calculate averages */
/* begin garbage collect for cells array */
if (reaped)
for(ar = NumCelAr - 1; ar > 0; ar--)
{ if (chk[ar])
break;
if (cells[ar])
{ tfree(cells[ar]);
cells[ar] = NULL;
}
NumCelAr--;
tcells = (Pcells Fp) trecalloc((Pcells Fp) cells,
(I32u) NumCelAr * sizeof(Pcells Fp),
(I32u) (NumCelAr + 1) * sizeof(Pcells Fp));
if (tcells)
cells = tcells;
else if (cells)
{ tfree(cells);
cells = NULL;
FEError(-129,EXIT,WRITE,"Tierra plan() cells trecalloc error\n");
}
CellsSize = NumCelAr * CelArSiz;
} /* end garbage collect for cells array */
if (chk)
{ tfree(chk);
chk = NULL;
}
#ifdef MEM_PROF /* calculate memory profile */
TotMemUse = SizSoup = SoupSize * sizeof(Instruction);
TotMemUse += SizCells = CellsSize * sizeof(struct cell);
TotMemUse += SizFreeMem = MaxFreeBlocks * sizeof(MemFr);
if(GeneBnker)
{ TotMemUse += SizSl = siz_sl * sizeof(SList Fp);
for (i = 0; i < siz_sl; i++)
{ if (sl[i])
{ TotMemUse += sizeof(SList);
SizSli += sizeof(SList);
TotMemUse += sl[i]->a_num * sizeof(GList Fp);
SizGl += sl[i]->a_num * sizeof(GList Fp);
for (j = 0; j < sl[i]->a_num; j++)
{ if ((I32s) sl[i]->g[j] > 4)
{ TotMemUse += sizeof(GList);
SizGli += sizeof(GList);
if (sl[i]->g[j]->genome)
{ TotMemUse += i * sizeof(Instruction);
SizGen += i * sizeof(Instruction);
}
if (sl[i]->g[j]->gbits)
{ TotMemUse += i * sizeof(GenBits);
SizGen += i * sizeof(GenBits);
}
}
}
}
}
}
#endif /* MEM_PROF */
/* begin calculate averages */
if (n != NumCells)
{ FEError(-130,EXIT,NOWRITE,
"Tierra plan() NumCells = %ld count of cells = %ld\n", NumCells, n);
}
AverageSize /= n;
if (GenPerMovMut)
RateMovMut = (I32s) 2L *GenPerMovMut * AverageSize;
indiv_gen_time = 10L * AverageSize;
if (InstExe.m)
pop_gen_time = NumCells * indiv_gen_time;
else pop_gen_time = indiv_gen_time * (SoupSize / (4L * AverageSize));
prob_of_hit = (double) AverageSize / (double) SoupSize;
if (GenPerBkgMut)
RateMut = (I32s) (pop_gen_time * 2L * GenPerBkgMut * prob_of_hit);
if (GenPerFlaw)
RateFlaw = (I32s) indiv_gen_time *GenPerFlaw * 2L;
if (DropDead) DropDead = 1L + AverageSize / 80L; /* DAN */
Search_limit = (Ind) (SearchLimit * AverageSize);
if (InstExe.m)
{ TimePop /= 1000000.;
Generations += (double) (TimeBirth + TimeDeath) / (2. * TimePop);
}
/* end calculate averages */
FEPlan(MaxPop, MaxMem, &MaxGenPop, &MaxGenMem);
#ifdef MEM_PROF
FEMemProf(SizSoup, SizCells, SizFreeMem, SizSl, SizSli,
SizGl, SizGli, SizGen);
#endif /* MEM_PROF */
TimePop = 0.;
TimeBirth = TimeDeath = 0L;
}
void GenExTemp(adrt, ce, tsize)
Ind adrt; /* address of beginning of template */
Pcells ce; /* ce = cell executing instruction */
I32s tsize; /* template size */
{
I32s i;
I32u who; /* 0 same cell; 1 daughter cell; 2 other cell; */
/* 3 free memory; 4 daughter of other cell */
Ind dist;
Pgl tgl, ogl;
Pcells ct;
tgl = sl[ce->d.gen.size]->g[ce->d.gi];
for (i = 0; i < tsize; i++)
{ ct = ce; /* WHAT TO DO WITH THIS? */
who = WhoIs(&ct, ad(ce->c.ip + 1 + i)); /* who has template pattern */
if (who < 4) tgl->bits |= (I32u) (ONE << (I32u) (12 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (12 + 2));
if (!who)
{ dist = ad(ce->c.ip + 1 + i) - ce->mm.p;
dist = ad(dist);
#ifdef ERROR
if (tgl->genome == NULL || dist < 0 || dist >= tgl->gen.size)
FEError(-131,EXIT,WRITE, "Tierra GenExTemp() error 0\n");
#endif /* ERROR */
#if PLOIDY == 1
tgl->gbits[dist] |= 1;
#else /* PLOIDY == 1 */
tgl->gbits[dist][ce->c.tr] |= 1;
#endif /* PLOIDY == 1 */
}
if (who == 2)
{ ogl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(ogl->bits, 0))
{ ogl->bits |= (I32u) (ONE << (I32u) (12 + 4));
dist = ad(ce->c.ip + 1 + i) - ct->mm.p;
dist = ad(dist);
#ifdef ERROR
if (ogl->genome == NULL || dist < 0 || dist >= ogl->gen.size)
FEError(-132,EXIT,NOWRITE, "Tierra GenExTemp() error 1\n");
#endif /* ERROR */
#if PLOIDY == 1
ogl->gbits[dist] |= (1 << 1);
#else /* PLOIDY == 1 */
ogl->gbits[dist][ce->c.tr] |= (1 << 1);
#endif /* PLOIDY == 1 */
}
}
ct = ce;
who = WhoIs(&ct, ad(adrt + i)); /* who has complementary template */
if (who < 4) tgl->bits |= (I32u) (ONE << (I32u) (7 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (7 + 2));
if (!who)
{ dist = ad(adrt + i) - ce->mm.p;
dist = ad(dist);
#ifdef ERROR
if (tgl->genome == NULL || dist < 0 || dist >= tgl->gen.size)
FEError(-133,EXIT,WRITE, "Tierra GenExTemp() error 2\n");
#endif /* ERROR */
#if PLOIDY == 1
tgl->gbits[dist] |= 1;
#else /* PLOIDY == 1 */
tgl->gbits[dist][ce->c.tr] |= 1;
#endif /* PLOIDY == 1 */
}
if (who == 2)
{ ogl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(ogl->bits, 0))
{ ogl->bits |= (I32u) (ONE << (I32u) (7 + 4));
dist = ad(adrt + i) - ct->mm.p;
dist = ad(dist);
#ifdef ERROR
if (ogl->genome == NULL || dist < 0 || dist >= ogl->gen.size)
FEError(-134,EXIT,WRITE, "Tierra GenExTemp() error 3\n");
#endif /* ERROR */
#if PLOIDY == 1
ogl->gbits[dist]|= (1 << 1);
#else /* PLOIDY == 1 */
ogl->gbits[dist][ce->c.tr] |= (1 << 1);
#endif /* PLOIDY == 1 */
}
}
}
}
void GenExMov(ce, to, from)
Pcells ce;
I32s to, from;
{
Pcells ct;
Pgl tgl, ogl;
I32u who; /* 0 same cell; 1 daughter cell; 2 other cell; */
/* 3 free memory; 4 daughter of other cell */
tgl = sl[ce->d.gen.size]->g[ce->d.gi];
if (ce->d.flaw || ce->d.mut || !IsBit(tgl->bits, 0))
return;
/* the mov instruction being executed is within your own genome */
if (ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s))
{ ct = ce;
who = WhoIs(&ct, from); /* who is it moved from */
if (who < 4) tgl->bits |= (I32u) (ONE << (I32u) (17 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (17 + 2));
if (who == 2)
{ ogl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(ogl->bits, 0))
ogl->bits |= (I32u) (ONE << (I32u) (17 + 4));
}
ct = ce;
who = WhoIs(&ct, to); /* who is it moved to */
if (who < 4)
tgl->bits |= (I32u) (ONE << (I32u) (22 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (22 + 2));
if (who == 2)
{ ogl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(ogl->bits, 0))
ogl->bits |= (I32u) (ONE << (I32u) (22 + 4));
}
}
else /* these are moved from while executing instructions that */
{ ct = ce; /* are not your own */
who = WhoIs(&ct, from); /* who is it moved from */
if (who < 4)
tgl->bits |= (I32u) (ONE << (I32u) (27 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (27 + 2));
if (who == 2) /* ct is cell from which inst is moved */
{ ogl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(ogl->bits, 0))
ogl->bits |= (I32u) (ONE << (I32u) (27 + 4));
}
}
}
void GenExExe(ce, adrt)
Pcells ce;
Ind adrt;
{
Pcells ct = ce;
Pgl tgl;
I32u dist;
I32u who; /* 0 same cell; 1 daughter cell; 2 other cell; */
/* 3 free memory; 4 daughter of other cell */
tgl = sl[ce->d.gen.size]->g[ce->d.gi];
if (ce->d.flaw || ce->d.mut || !IsBit(tgl->bits, 0))
return;
who = WhoIs(&ct, adrt);
if (who < 4)
tgl->bits |= (I32u) (ONE << (I32u) (2 + who));
else tgl->bits |= (I32u) (ONE << (I32u) (2 + 2));
if (!who) /* who == 0 == same cell */
{ dist = adrt - ce->mm.p;
#ifdef ERROR
if (tgl->gbits == NULL || dist < 0 || dist >= tgl->gen.size)
FEError(-135,EXIT,WRITE, "Tierra GenExExe() error 0\n");
#endif /* ERROR */
#if PLOIDY == 1
tgl->gbits[dist]|= 1;
#else /* PLOIDY == 1 */
tgl->gbits[dist][ce->c.tr] |= 1;
#endif /* PLOIDY == 1 */
}
if (who == 2) /* is other cell */
{ tgl = sl[ct->d.gen.size]->g[ct->d.gi];
if (IsBit(tgl->bits, 0))
{ tgl->bits |= (ONE << (I32u) (2 + 4));
dist = adrt - ct->mm.p;
#ifdef ERROR
if (tgl->gbits == NULL || dist < 0 || dist >= tgl->gen.size)
FEError(-136,EXIT,WRITE, "Tierra GenExExe() error 1\n");
#endif /* ERROR */
#if PLOIDY == 1
tgl->gbits[dist]|= (1 << 1);
#else /* PLOIDY == 1 */
tgl->gbits[dist][ce->c.tr] |= (1 << 1);
#endif /* PLOIDY == 1 */
}
}
}