|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 4492 (0x118c) Types: TextFile Names: »gen.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Life/gen.c«
#ifdef SCCS static char *sccsid = "@(#)gen.c 1.4 2/2/85"; static char *cpyrid = "@(#)Copyright (C) 1985 by D Bell"; #endif #include "life.h" char rules[18] = {0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0}; /* life rules */ /* * Compute one full generation of the current configuration. * This is done by calling computerow with each triple of rows which * contain any live cells, and remembering the result. When all rows * are finished, we change the object. */ dogeneration(obj) struct object *obj; /* object to compute */ { register struct row *prp; /* previous row */ register struct row *crp; /* current row */ register struct row *nrp; /* next row */ register struct row *newrp; /* current row of new list */ register struct row *srp; /* saved row pointer */ int row; /* current row number */ if (genleft <= 0) return; if ((--genleft == 0) || (--freqcount <= 0)) redraw = 1; obj->o_gen++; obj->o_born = 0; obj->o_died = 0; newrp = &initrow; prp = termrow; crp = termrow; nrp = obj->o_firstrow; srp = nrp->r_next; row = nrp->r_row - 1; while (1) { /* loop over each triple of rows */ if (row >= (INFINITY-1)) break; prp = computerow(obj, prp, crp, nrp); if (prp) { /* have something in current row */ newrp->r_next = prp; newrp = prp; newrp->r_row = row; obj->o_count += prp->r_count; } row++; prp = crp; crp = nrp; nrp = srp; if (nrp->r_row == row + 1) { srp = nrp->r_next; continue; } nrp = termrow; if ((prp != termrow) || (crp != termrow)) continue; nrp = srp; srp = nrp->r_next; row = nrp->r_row - 1; } zeroobject(obj); if (newrp == &initrow) { /* died off */ genleft = 0; redraw = 1; return; } obj->o_firstrow = initrow.r_next; newrp->r_next = termrow; obj->o_lastrow = newrp; if ((obj->o_born == 0) && (obj->o_died == 0)) { /* no change */ genleft = 0; redraw = 1; } } /* * Compute the result of three adjacent rows, and return a row structure * containing the new middle row, or NULL if no live cells are produced. * When determining if a cell is dead or alive, each live neighbor counts * as a 1, but the current cell counts as 9 when alive. Indexing the rules * table with the sum then automatically produces the correct result. */ struct row * computerow(obj, prevrow, currow, nextrow) struct object *obj; struct row *prevrow, *currow, *nextrow; { register struct cell *pcp; /* head of previous row of cells */ register struct cell *ccp; /* head of current row of cells */ register struct cell *ncp; /* head of next row of cells */ register struct cell *tcp; /* temporary cell */ register struct cell *newcp; /* new row of cells */ register int i; /* sum of live cells and other uses */ struct row *rp; /* new row pointer */ int col; /* current column being examined */ int colp1; /* one more than column */ int count; /* live cells */ pcp = prevrow->r_firstcell; ccp = currow->r_firstcell; ncp = nextrow->r_firstcell; newcp = &initcell; count = 0; col = -INFINITY; while (1) { /* loop over cells of all 3 rows */ /* * Find next column where a cell exists on any row */ i = col - 1; while (i > pcp->c_col) pcp = pcp->c_next; while (i > ccp->c_col) ccp = ccp->c_next; while (i > ncp->c_col) ncp = ncp->c_next; i = ccp->c_col; if (pcp->c_col < i) i = pcp->c_col; if (ncp->c_col < i) i = ncp->c_col; if (i == INFINITY) break; i--; if (col < i) col = i; i = 0; colp1 = col + 1; if (pcp->c_col <= colp1) { /* add cells in previous row */ i++; tcp = pcp->c_next; i += (tcp->c_col <= colp1); tcp = tcp->c_next; i += (tcp->c_col <= colp1); } if (ccp->c_col <= colp1) { /* add cells on our row */ i++; tcp = ccp->c_next; if ((ccp->c_col == col) || (tcp->c_col == col)) { i += (LIFE - 1); } i += (tcp->c_col <= colp1); tcp = tcp->c_next; i += (tcp->c_col <= colp1); } if (ncp->c_col <= colp1) { /* add cells in next row */ i++; tcp = ncp->c_next; i += (tcp->c_col <= colp1); tcp = tcp->c_next; i += (tcp->c_col <= colp1); } if (rules[i]) { /* cell is alive */ obj->o_born += (i < LIFE); tcp = alloccell(); tcp->c_col = col; newcp->c_next = tcp; newcp = tcp; count++; } else /* cell is dead */ obj->o_died += (i >= LIFE); col++; } if (newcp == &initcell) return(NULL); newcp->c_next = termcell; rp = allocrow(); rp->r_firstcell = initcell.c_next; rp->r_lastcell = newcp; rp->r_count = count; return(rp); }