home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol028 / life-c.c < prev    next >
C/C++ Source or Header  |  1984-04-29  |  7KB  |  313 lines

  1.  
  2. /*
  3.     "LIFE"
  4.  
  5.     The game invented by John Conway
  6.  
  7.     This version written by Leor Zolman to exemplify
  8.     PROPER use of"goto" statements in C programs!
  9.  
  10.     Note that the Universe is a toroid;
  11.     The left extreme is adjacent to the right extreme,
  12.     the top is adjacent to the bottom, and each corner
  13.     is adjacent to each other corner.
  14.     In other words, there ARE NO EXTREMES !!
  15.     Or, in a more physical illustration: If you could
  16.     look straight ahead through an infinitely powerful
  17.     telescope, you'd eventually see the back of your
  18.     head....
  19.  
  20. */
  21.  
  22. #define CLEARS 0x1a    /* character to clear your screen */
  23.             /* If no single character does this
  24.                on your terminal, make this a
  25.                newline ('\n')        */
  26. #define TWIDTH 64     /* # of columns on your terminal */
  27. #define XSIZE 60    /* length of cell array  */
  28. #define YSIZE 65    /* width of cell array */
  29.             /* To see how the toroid works,
  30.                try reducing XSIZE and YSIZE to
  31.                around 10 or 20.        */
  32. #define BOREDOM_THRESHOLD 5  /* This is how many generations
  33.                 are allowed to pass without a
  34.                 population change */
  35.  
  36. char *gets();        /* routine to accept a line of input */
  37. char cell[XSIZE][YSIZE]; /* the universe matrix */
  38. int minx, maxx, miny, maxy, pop, gen;    /* misc. variables */
  39. char doneflag;       /* This goes true when we want to stop */
  40. int boring;        /* keeps count of how many generations
  41.                go by without a population change */
  42. char center;        /* 1 = center display; 0 = left
  43.                            justify */
  44.  
  45. main()
  46. {
  47.     char c;
  48.     printf("\n\t *** BDS Life ***\n");
  49.     printf("\nDo you wish to have the display centered\n");
  50.     printf(" (and thereby slowed down a bit) (y/n) ?");
  51.     center = toupper(getchar()) == 'Y';
  52.     for (;;) {
  53.       clear();
  54.       setup();
  55.       if (!pop) break;
  56.       adjust();
  57.       display();
  58.       while (pop) {
  59.         adjust();
  60.         dogen();
  61.         display();
  62.         if (boring == BOREDOM_THRESHOLD) {
  63.           boring++;
  64.           printf("\nNo change in population for");
  65.           printf(" %d ",BOREDOM_THRESHOLD);
  66.           printf("generations. Abort (y/n) ");
  67.           c = toupper(getchar());
  68.           putchar('\n');
  69.           if (c == 'Y') break;
  70.          }
  71.         if (kbhit()) {getchar(); break;}
  72.         if (doneflag) break;
  73.        }
  74.      }
  75.  }
  76.  
  77. /* initialize the cell matrix to all dead */
  78. clear()
  79. {
  80.     setmem(cell,(XSIZE*YSIZE),0);
  81. }
  82.  
  83. /* get initial set-up from user */
  84. setup()
  85. {
  86.     char c,y;
  87.     char string[YSIZE], *ptr;
  88.     y = pop = gen = minx = maxx = miny= maxy = 0;
  89.     boring = 0;
  90.     printf("\nEnter initial configuration (null line to end):\n");
  91.  
  92.     while (*gets(string)) {
  93.         ptr = string;
  94.         while (*ptr) {
  95.             if ( *ptr++ != ' ') {
  96.                 cell[maxx][y] = 10;
  97.                 ++pop;
  98.              }
  99.             ++y;
  100.             if (y==YSIZE) {
  101.              printf("Truncated to %d chars\n",
  102.                  YSIZE); break;
  103.              }
  104.          }
  105.         --y;
  106.         ++maxx;
  107.         if (y>maxy) maxy = y;
  108.         if (maxx==XSIZE) break;
  109.         y = 0;
  110.      }
  111.     --maxx;
  112. }
  113.  
  114. /* display the current generation */
  115. display()
  116. {
  117.     int i,j,k,l,j9;
  118.     char c;
  119.  
  120.     if (!pop) {
  121.         printf("\nLife ends at %d\n",gen);
  122.         return;
  123.      }
  124.     if(minx && prow(minx-1)) minx--;
  125.     if(miny && pcol(miny-1)) miny--;
  126.     if ((maxx < (XSIZE-1)) && prow(maxx+1)) maxx++;
  127.     if((maxy<(YSIZE-1)) && pcol(maxy+1))maxy++;
  128.     
  129.     while (!prow(minx)) minx++;
  130.     while (!prow(maxx)) maxx--;
  131.     while (!pcol(miny)) miny++;
  132.     while (!pcol(maxy)) maxy--;
  133.  
  134.     putchar(CLEARS);
  135.     if (center) {
  136.         i = (TWIDTH-33)/2;
  137.         for (j = 0; j<i; j++) putchar(' ');
  138.     }
  139.     printf("generation = %1d   population = %1d\n",
  140.         gen,pop);
  141.     ++gen;
  142.  
  143.     j9 = maxy - miny + 1;
  144.     for (i = minx; i<=maxx; i++) {
  145.         if (center && j9<TWIDTH) {
  146.             l = (TWIDTH-j9)/2;
  147.             for (k = 0; k<l; k++) putchar(' ');
  148.          }
  149.         for (j=miny; j<=maxy; j++)
  150.             putchar(cell[i][j] ? '*' : ' ');
  151.         if (i != maxx) putchar('\n');
  152.     }
  153. }
  154.  
  155. /* test if given column is populated */
  156. pcol(n)
  157. {
  158.     int i,hi;
  159.     hi = (maxx == (XSIZE-1)) ? maxx : maxx+1;
  160.     for (i = minx ? minx-1 : minx; i<=hi; ++i)
  161.         if (cell[i][n]) return 1;
  162.     return 0;
  163. }
  164.  
  165. /* test if given row is populated */
  166. prow(n)
  167. {
  168.     int i,hi;
  169.     hi = (maxy == (YSIZE-1)) ? maxy : maxy+1;
  170.     for (i = miny ? miny-1 : miny; i<=hi; ++i)
  171.         if (cell[n][i]) return 1;
  172.     return 0;
  173. }
  174.  
  175.  
  176.  
  177. /* compute next generation */
  178. dogen()
  179. {
  180.     int i,j,i2,j2;
  181.     int bigflag;
  182.     int k,l;
  183.     int oldpop;
  184.     char c;
  185.     int pass;
  186.     doneflag = 1;
  187.     oldpop = pop;
  188.     bigflag =  (minx<2 || maxx>(XSIZE-3) ||
  189.         miny<2 || maxy>(YSIZE-3)) ;
  190.     i2 = (maxx==(XSIZE-1)) ? maxx : maxx+1;
  191.     j2 = (maxy==(YSIZE-1)) ? maxy : maxy+1;
  192.     for (pass = 0; pass < 2; pass++)
  193.     for (i=minx ? minx-1 : minx; i<=i2; ++i)
  194.       for (j=miny ? miny-1 : miny; j<=j2; ++j) {
  195.        c = cell[i][j];
  196.        if (!pass) {
  197.          if (c >= 10)
  198.         if (bigflag)
  199.           for (k = -1; k <= 1; k++)
  200.            for (l = -1; l <= 1; l++)
  201.             cell[mod(i+k,XSIZE)][mod(j+l,YSIZE)]++;
  202.         else
  203.           for (k = -1; k<=1; k++)
  204.            for (l = -1; l <= 1; l++)
  205.             cell[i+k][j+l]++;
  206.         }
  207.        else
  208.          if (c > 10)
  209.         if (c < 13 || c > 14) {
  210.             cell[i][j] = 0;
  211.             pop--;
  212.             doneflag = 0;
  213.          }
  214.         else cell[i][j] = 10;
  215.          else
  216.         if (c == 3) {
  217.             cell[i][j] = 10;
  218.             pop++;
  219.             doneflag = 0;
  220.          }
  221.         else cell[i][j] = 0;
  222.      }
  223.     if (pop == oldpop) boring++;
  224.       else boring = 0;
  225. }
  226.  
  227.  
  228. int mod(a,b)
  229. {
  230.     if (a<0) return b+a;
  231.     if (a<b) return a;
  232.     return a-b;
  233. }
  234.  
  235.  
  236. /* If we're about to run off the matrix, adjust accordingly (if possible) */
  237. adjust()
  238. {
  239.     adjx();
  240.     adjy();
  241. }
  242.  
  243. /* Adjust vertical position */
  244. adjx()
  245. {
  246.     int delta, i,j;
  247.     int savdelta;
  248.     if (maxx - minx + 1 > XSIZE-2) return;
  249.     if (minx==0) {
  250.         delta = (XSIZE-maxx)/2+maxx;
  251.         savdelta = delta;
  252.         for (i=maxx; i >= 0; --i) {
  253.             for (j=miny; j<=maxy; ++j) {
  254.                 cell[delta][j] = cell[i][j];
  255.                 cell[i][j] = 0;
  256.              }
  257.         --delta;
  258.         }
  259.         minx = delta+1;
  260.         maxx = savdelta;
  261.     }
  262.  
  263.     if (maxx == (XSIZE-1)) {
  264.         delta = minx/2;
  265.         savdelta = delta;
  266.         for (i=minx; i<XSIZE; ++i) {
  267.             for (j=miny; j<=maxy; ++j) {
  268.                 cell[delta][j] = cell[i][j];
  269.                 cell[i][j] = 0;
  270.             }
  271.         ++delta;
  272.         }
  273.         maxx = delta-1;
  274.         minx = savdelta;
  275.     }
  276. }
  277.  
  278.  
  279. /* Adjust horizontal position */
  280. adjy()
  281. {
  282.     int delta, i, j;
  283.     int savdelta;
  284.     if (maxy - miny + 1 > YSIZE -2) return;
  285.     if (miny == 0) {
  286.         delta = (YSIZE-maxy)/2+maxy;
  287.         savdelta = delta;
  288.         for (i=maxy; i>=0; --i) {
  289.             for (j=minx; j<=maxx; ++j) {
  290.                 cell[j][delta] = cell[j][i];
  291.                 cell[j][i] = 0;
  292.             }
  293.         --delta;
  294.         }
  295.         miny = delta+1;
  296.         maxy = savdelta;
  297.     }
  298.  
  299.     if (maxy == (YSIZE-1)) {
  300.         delta = miny/2;
  301.         savdelta = delta;
  302.         for (i=miny; i<YSIZE; ++i) {
  303.             for (j=minx; j<=maxx; ++j) {
  304.                 cell[j][delta] = cell[j][i];
  305.                 cell[j][i] = 0;
  306.             }
  307.         ++delta;
  308.         }
  309.         maxy = delta -1;
  310.         miny = savdelta;
  311.     }
  312. }
  313.