dos_compilers/DeSmet C88 v24/LIFE.C

254 lines
5.8 KiB
C++
Raw Normal View History

2024-06-30 23:24:37 +02:00
/* LIFE.C The much implemented game of Life invented by John Conway
This version was written to illustrate the use of the C88
screen and keyboard interface. Use C option for color display.
To generate:
A>C88 B:LIFE
A>ASM88 B:PCIO
A>BIND B:LIFE B:PCIO */
/*
global constant and data declarations
*/
#define ROWS 24
#define COLS 80
/* control key translations */
#define up_char 30
#define down_char 31
#define left_char 29
#define right_char 28
#define bol_char 200
#define eol_char 201
#define pageup_char 202
#define pagedown_char 203
#define bof_char 204
#define eof_char 205
#define Ins_char 206
#define Del_char 207
#define NextWord_char 208
#define PrevWord_char 209
/* function keys */
#define M1 210
#define M2 211
#define M3 212
#define M4 213
#define M5 214
#define M6 215
#define M7 216
#define M8 217
#define M9 218
#define M10 219
char world[ROWS][COLS],create_mode=1,quit_flag;
int population,generation,crow,ccol;
char color_opt,color;
main(argc,argv)
int argc;
char *argv[]; {
if (argc > 1 && toupper(*argv[1]) == 'C') color_opt=1;
scr_setup();
scr_clr();
instruct();
setup();
do {
generation++;
cycle();
screen();
}
while (population && !quit_flag);
scr_rowcol(ROWS,10);
if (population == 0)
puts("Nobody left, sorry about that. ");
else puts("bye ");
scr_curson();
}
instruct() { /* print instructions */
puts(" The game of Life by John Conway\n\n");
puts(" Use LIFE C with color monitor.\n");
puts(" If started with a number, a random pattern starts the game.\n\n");
puts(" Otherwise, move the cursor with the four arrow keys to create life.\n\n");
puts(" DEL changes cursor movement to mean that cells are deleted\n\n");
puts(" INS flips back to create mode.\n\n");
puts(" The '+' key will toggle the game on or off.\n\n");
puts(" Hit ESC to bail out.\n\n");
puts(" Enter starting number of cells or hit CR ");
}
setup() {
int rnumber;
int i,row,col,seed,rnum;
char ch;
rnumber=0;
while (1) {
while ((ch=scr_csts()) == 0) seed++;
if (ch < '0' || ch > '9') break;
scr_co(ch);
rnumber*=10;
rnumber+=ch-'0';
}
scr_cursoff();
scr_clr();
scr_rowcol(ROWS,20); /* print population message */
puts("Generation 0 Population 0");
srand(seed); /* initilize random number generator */
for (i=0; i < rnumber; i++) {
rnum=rand();
row=rnum%ROWS;
col=(rnum/ROWS)%COLS;
world[row][col]='X'; /* put in a cell */
scr_rowcol(row,col);
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
}
if (rnumber == 0) create(1);
}
screen() { /* update the screen and set world back to x's */
int row,col;
char cell;
population=0;
for (row=0; row < ROWS; row++) {
for (col=0; col < COLS; col++) {
cell=world[row][col];
/* stay alive if 3 neighbors, born if next to 2 or 3 */
if (cell && (cell == 3 || cell == 'X'+2 || cell == 'X'+3)) {
population++;
if (cell < 'X') {
scr_rowcol(row,col);
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
}
cell='X';
}
else {
if (cell >= 'X') {
scr_rowcol(row,col);
scr_co(' ');
}
cell=0;
}
world[row][col]=cell;
}
}
scr_rowcol(ROWS,31);
printf("%4d",generation);
scr_rowcol(ROWS,51);
printf("%4d",population);
}
create(suspend) /* see if need to create or kill cells */
char suspend; {
char ch,wait;
while ((ch=scr_csts()) || suspend) {
switch (ch) {
case up_char: crow=crow ? crow-1: ROWS-1;
break;
case down_char: crow=crow == ROWS-1 ? 0: crow+1;
break;
case left_char: ccol=ccol ? ccol-1: COLS-1;
break;
case right_char:ccol=ccol == COLS-1 ? 0: ccol+1;
break;
case bol_char: ccol=0;
break;
case eol_char: ccol=COLS-1;
break;
case '+': suspend=!suspend;
continue;
case Ins_char: create_mode=1;
continue;
case Del_char: create_mode=0;
continue;
case 0x1b: quit_flag=1; /* flag for stop */
return;
default: continue;
}
world[crow][ccol]= create_mode ? 'X': 0;
scr_rowcol(crow,ccol);
if (create_mode) {
if (color_opt) scr_aputs("\2",++color | 0X80);
else scr_co(2);
population++;
}
else {
wait=30;
while (wait--) {
if (color_opt) scr_aputs("\1",++color | 0X80);
else scr_co(1);
scr_rowcol(crow,ccol);
}
scr_co(' ');
}
}
}
cycle() { /* cycle to the next generation */
int row,col;
create(0);
/* take care of left and right column first */
for (row=0; row < ROWS; row++) {
if (world[row][0] >= 'X') add8(row,0);
if (world[row][COLS-1] >= 'X') add8(row,COLS-1);
}
/* take care of top and bottom line */
for (col=1; col < COLS-1;col++) {
if (world[0][col] >= 'X') add8(0,col);
if (world[ROWS-1][col] >= 'X') add8(ROWS-1,col);
}
/* fill in the box, ignoring border conditions */
for (row=1; row < ROWS-1; row++) {
for (col=1; col < COLS-1; col++) {
if (world[row][col] >= 'X' ) {
world[row-1][col-1]++;
world[row-1][col]++;
world[row-1][col+1]++;
world[row][col-1]++;
world[row][col+1]++;
world[row+1][col-1]++;
world[row+1][col]++;
world[row+1][col+1]++;
}
}
}
}
add8(row,col)
int row,col; {
int rrow,ccol,rr,cc;
for (rr=row-1; rr <= row+1; rr++) {
for (cc=col-1; cc <= col+1; cc++) {
rrow=rr != -1 ? rr : ROWS-1;
ccol=cc != -1 ? cc : COLS-1;
if (rrow >= ROWS) rrow=0;
if (ccol >= COLS) ccol=0;
world[rrow][ccol]++;
}
}
world[row][col]--;
}