home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
microcrn
/
issue_45.arc
/
LIFE.ARC
/
LIFE.C
< prev
next >
Wrap
Text File
|
1988-04-02
|
7KB
|
270 lines
/* Micro Cornucopia Magazine Issue #45
Life Figure 1 LIFE.C
Hard coded for CGA */
#include <graphics.h>
#define BYTE unsigned char
#define WORD unsigned int
#define FALSE 0
#define TRUE 1
/* rule parameters governing births and deaths */
#define EL 2 /*envrnmnt,lower:death if n_cnt<EL*/
#define EU 3 /*envrnmnt,upper: or n_cnt>EU*/
#define FL 3 /*fertlty,lower:birth if n_cnt>=FL*/
#define FU 3 /*fertlty,upper: and n_cnt<=FU*/
/* configuration constants (array sizes) */
#define MAX_ALIVE 600 /* max # living cells */
#define MAX_GHOST 1700/*max # non-live neighbors*/
#define MAX_BIRTH 300/* max # births/generation */
#define MAX_DEATH 300/* max # deaths/generation */
#define MAX_X 200 /* width of grid */
#define MAX_Y 200 /* height of grid */
/* global variable declarations */
BYTE n_cnt[MAX_X][MAX_Y]; /* neighbor count ... */
/* ... for all cells */
BYTE alive[2][MAX_ALIVE]; /* list/living cells */
BYTE ghost[2][MAX_GHOST]; /*list/neighbor cells*/
BYTE birth[2][MAX_BIRTH]; /* list/new births */
BYTE death[2][MAX_DEATH]; /* list/new deaths */
WORD alive_cnt; /* size of list of living cells */
WORD ghost_cnt; /* size of list of neighbors */
WORD birth_cnt; /* size of list of births */
WORD death_cnt; /* size of list of deaths */
void locate_deaths(void)
{
BYTE c, x, y;
WORD index;
death_cnt = index = 0;
while (index < alive_cnt)
{
x = alive[0][index]; y = alive[1][index];
c = n_cnt[x][y] - 1;
if (c >= EL && c <= EU) index++;
else
{
death[0][death_cnt] = x;
death[1][death_cnt] = y;
death_cnt++;
alive_cnt--;
alive[0][index] = alive[0][alive_cnt];
alive[1][index] = alive[1][alive_cnt];
}
}
}
void locate_births(void)
{
BYTE c, x, y;
WORD index;
birth_cnt = index = 0;
while (index < ghost_cnt)
{
x = ghost[0][index]; y = ghost[1][index];
c = n_cnt[x][y];
if (c >= FL && c <= FU)
{
if (x > 0 && y > 0 && x < MAX_X-1 &&
y < MAX_Y-1)
{
birth[0][birth_cnt] = x;
birth[1][birth_cnt] = y;
birth_cnt++;
}
ghost_cnt--;
ghost[0][index] = ghost[0][ghost_cnt];
ghost[1][index] = ghost[1][ghost_cnt];
}
else if (c == 0)
{
ghost_cnt--;
ghost[0][index] = ghost[0][ghost_cnt];
ghost[1][index] = ghost[1][ghost_cnt];
}
else index++;
}
}
void process_births(void)
{
BYTE x, y;
WORD index;
for (index = 0; index < birth_cnt; index++)
{
x = alive[0][alive_cnt] = birth[0][index];
y = alive[1][alive_cnt] = birth[1][index];
alive_cnt++;
n_cnt[x][y]++;
x++;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
y++;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
x--;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
x--;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
y--;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
y--;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
x++;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
x++;
if (n_cnt[x][y]++ == 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
}
}
void process_deaths(void)
{
BYTE i, j, x, y;
WORD index;
for (index = 0; index < death_cnt; index++)
{
x = death[0][index];
y = death[1][index];
for (i = x - 1; i < x + 2; i++)
for (j = y - 1; j < y + 2; j++)
n_cnt[i][j]--;
}
for (index = 0; index < death_cnt; index++)
{
x = death[0][index];
y = death[1][index];
if (n_cnt[x][y] != 0)
{
ghost[0][ghost_cnt] = x;
ghost[1][ghost_cnt] = y;
ghost_cnt++;
}
}
}
void screen_update(void)
{
BYTE x, y;
WORD index;
for (index = 0; index < birth_cnt; index++)
{
x = birth[0][index]; y = birth[1][index];
putpixel(x, y, 1);
}
for (index = 0; index < death_cnt; index++)
{
x = death[0][index]; y = death[1][index];
putpixel(x, y, 2);
}
}
void init_grid(void)
{
BYTE x, y;
WORD index;
for (x = 0; x < MAX_X; x++)
for (y = 0; y < MAX_Y; y++)
n_cnt[x][y] = 0;
birth[0][0] = 100; birth[1][0] = 100;
birth[0][1] = 101; birth[1][1] = 100;
birth[0][2] = 102; birth[1][2] = 100;
birth[0][3] = 102; birth[1][3] = 99;
birth[0][4] = 101; birth[1][4] = 101;
birth_cnt = 5; alive_cnt = 0;
ghost_cnt = 0;
screen_update();
for (index = 0; index < birth_cnt; index++)
{
x = birth[0][index]; y = birth[1][index];
n_cnt[x][y]++;
}
process_births();
for (index = 0; index < birth_cnt; index++)
{
x = birth[0][index]; y = birth[1][index];
n_cnt[x][y]--;
}
}
void main(void)
{
int step = FALSE; int done = FALSE;
int generation = 0;
int gd = CGA; int gm = CGAC0;
initgraph(&gd, &gm, "");
printf("Generation: 0 Run Pause Step Quit");
init_grid();
gotoxy(1, 1); getch();
while (!done)
{
gotoxy(13, 1); printf("%d", ++generation);
locate_deaths(); locate_births();
process_births(); process_deaths();
screen_update();
if (kbhit() || step)
{
switch(toupper(getch()))
{
case 'Q': done = TRUE;
break;
case 'P': getch();
break;
case 'S': step = 1;
break;
case 'R': step = 0;
break;
}
}
}
closegraph();
}