/* "LIFE" The game invented by John Conway ************************************************* * This version specially configured for * * the H19 terminal (and its 25th line) * ************************************************* This version written by Leor Zolman to exemplify PROPER use of"goto" statements in C programs! Compile with the "-o" option to CC1 for best per- formance. Note that the Universe is a toroid; i.e, the left extreme is adjacent to the right extreme, the top is adjacent to the bottom, and each corner is adjacent to each other corner. In other words, there ARE NO EXTREMES !! Or, in a more physical illustration: If I could take a peek straight ahead through the magical eyepiece of an infinitely powerful telescope, I'd be able to see the back of my brain-damaged head....that is, of course, assuming no galaxies or cats get in the way. */ #define SILENT 0 /* comment out this line to enable data display */ #define CLEARS "\033E\033y1\033x1\033x5" #define TWIDTH 80 /* # of columns on your terminal */ #define XSIZE 100 /* length of cell array (max # of lines)*/ #define YSIZE 90 /* width of cell array */ /* To see how the toroid works, try reducing XSIZE and YSIZE to around 10 or 20. */ #define BOREDOM_THRESHOLD 5 /* This is how many generations are allowed to pass without a population change before Divine intervention is called for. */ char *gets(); /* routine to accept a line of input */ char cell[XSIZE][YSIZE]; /* the universe matrix */ int minx, maxx, miny, maxy, pop, gen; /* misc. variables */ char doneflag; /* This goes true when we want to stop */ int boring; /* keeps count of how many generations go by without a population change */ /* The main driving routine, to accept random initial and population configurations, and display their evolution according to a proximity-based formula. */ main() { char c; printf("%s\n\t**** BDS Life ****\n\n",CLEARS); printf( "\tSpecial H19 Version\n\n"); for (;;) { clear(); setup(); if (!pop) break; adjust(); display(); while (pop) { adjust(); dogen(); if (kbhit()) { getchar(); puts("\033y1\033x1\033j\033Y89"); printf("The Wrath Of God Strikes! KA-BEEP!\7"); puts("\033K\033k\033y5\n"); sleep(10); break; } display(); if (boring == BOREDOM_THRESHOLD) { boring++; printf("\033j\033y5\033y1\033x1\033Y8 No change in "); printf("population for %d ",BOREDOM_THRESHOLD); printf("generations. Abort? (y/n) "); c = toupper(getchar()); puts("\033k"); if (c == 'Y') break; } if (doneflag) break; } } puts("\033z"); } /* Initialize the cell matrix to all dead */ clear() { setmem(cell,(XSIZE*YSIZE),0); } /* Get initial set-up from user */ setup() { char c; int y; char string[YSIZE], *ptr; y = pop = gen = minx = maxx = miny= maxy = 0; boring = 0; printf("\033y5"); printf("\n\nEnter initial configuration (single period to end):\n"); while (*gets(string) != '.') { ptr = string; while (*ptr) { if ( *ptr++ != ' ') { cell[maxx][y] = 10; ++pop; } ++y; if (y==YSIZE) { printf("Truncated to %d chars\n", YSIZE); break; } } --y; ++maxx; if (y>maxy) maxy = y; if (maxx==XSIZE) break; y = 0; } --maxx; printf(CLEARS); } /* Display the current generation */ display() { int i,j,k,l,j9; char c; char line; char *cline; puts("\033x5"); /* shut off blinking cursor */ if (!pop) { printf("\033y1\033x1\033j\033Y89Life ends at %d\033k\033y5\7", gen); sleep(20); return; } if(minx && prow(minx-1)) minx--; if(miny && pcol(miny-1)) miny--; if ((maxx < (XSIZE-1)) && prow(maxx+1)) maxx++; if((maxy<(YSIZE-1)) && pcol(maxy+1))maxy++; while (!prow(minx)) minx++; while (!prow(maxx)) maxx--; while (!pcol(miny)) miny++; while (!pcol(maxy)) maxy--; if (!doneflag) { #ifndef SILENT printf("\033y1\033x1\033j\033Y87generation = %3d population = %3d", gen,pop); puts("\033k\033E"); #endif ;} else puts("\033y5\033E"); ++gen; line = 255; if (maxx - minx < 23) { line += (23 - (maxx - minx))/2; printf("\033Y%co\033b",line+' '); } j9 = maxy - miny + 1; for (i = minx; i<=maxx; i++) { cline = cell[i] + miny; if (line == 23) putchar('\n'); else line++; l = (j9(XSIZE-3) || miny<2 || maxy>(YSIZE-3)) ; i2 = (maxx==(XSIZE-1)) ? maxx : maxx+1; j2 = (maxy==(YSIZE-1)) ? maxy : maxy+1; for (pass = 0; pass < 2; pass++) for (i=minx ? minx-1 : minx; i<=i2; ++i) for (j=miny ? miny-1 : miny; j<=j2; ++j) { c = cell[i][j]; if (!pass) { if (c >= 10) if (bigflag) for (k = -1; k <= 1; k++) for (l = -1; l <= 1; l++) cell[mod(i+k,XSIZE)][mod(j+l,YSIZE)]++; else for (k = -1; k<=1; k++) for (l = -1; l <= 1; l++) cell[i+k][j+l]++; } else if (c > 10) if (c < 13 || c > 14) { cell[i][j] = 0; pop--; doneflag = 0; } else cell[i][j] = 10; else if (c == 3) { cell[i][j] = 10; pop++; doneflag = 0; } else cell[i][j] = 0; } if (pop == oldpop) boring++; else boring = 0; if (doneflag) { printf("\033y1\033x1\033j\033Y89Static configuration reached\033k\7"); sleep(20); } } int mod(a,b) { if (a<0) return b+a; if (a XSIZE-2) return; if (minx==0) { delta = (XSIZE-maxx)/2+maxx; savdelta = delta; for (i=maxx; i >= 0; --i) { for (j=miny; j<=maxy; ++j) { cell[delta][j] = cell[i][j]; cell[i][j] = 0; } --delta; } minx = delta+1; maxx = savdelta; } if (maxx == (XSIZE-1)) { delta = minx/2; savdelta = delta; for (i=minx; i YSIZE -2) return; if (miny == 0) { delta = (YSIZE-maxy)/2+maxy; savdelta = delta; for (i=maxy; i>=0; --i) { for (j=minx; j<=maxx; ++j) { cell[j][delta] = cell[j][i]; cell[j][i] = 0; } --delta; } miny = delta+1; maxy = savdelta; } if (maxy == (YSIZE-1)) { delta = miny/2; savdelta = delta; for (i=miny; i