00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <sys/types.h>
00012 #include <signal.h>
00013 #include <time.h>
00014 #include <curses.h>
00015 #include <stdlib.h>
00016 #include <unistd.h>
00017 #include <stdio.h>
00018
00019 #if __minix_vmd
00020 #define srand(seed) srandom(seed)
00021 #define rand() random()
00022 #endif
00023
00024
00025
00026 #define REPSTOP -1
00027
00028 int present[23][80];
00029 int past[23][80];
00030 int total;
00031 int icnt;
00032 int maxrow = 22;
00033 int maxcol = 79;
00034 int minrow = 0;
00035 int mincol = 0;
00036 int pri = 0;
00037 int draw = 0;
00038 int i, j, k;
00039 int cycle;
00040 int changes;
00041 int die;
00042 int live;
00043
00044 WINDOW *mns;
00045 WINDOW *info;
00046
00047 _PROTOTYPE(void cleanup, (int s));
00048 _PROTOTYPE(void initialize, (void));
00049 _PROTOTYPE(void makscr, (void));
00050 _PROTOTYPE(void update, (void));
00051 _PROTOTYPE(void print, (void));
00052 _PROTOTYPE(int main, (int ac, char *av[]));
00053
00054
00055 void cleanup(s)
00056 int s;
00057 {
00058 move(23, 0);
00059 refresh();
00060
00061 endwin();
00062 exit(1);
00063 }
00064
00065
00066
00067 void initialize()
00068 {
00069 srand(getpid());
00070 initscr();
00071 noecho();
00072 curs_set(0);
00073 signal(SIGINT, cleanup);
00074 mns = newwin(maxrow, maxcol, 0, 0);
00075 scrollok(mns, FALSE);
00076 info = newwin(1, 80, 23, 0);
00077 scrollok(info, FALSE);
00078 wclear(mns);
00079 wclear(info);
00080 wmove(info, 0, 0);
00081 wrefresh(info);
00082 if (!draw) {
00083 for (j = 0; j < maxrow; j++) {
00084 for (k = 0; k < maxcol; k++) {
00085 present[j][k] = rand() % 2;
00086 if (present[j][k] == 1) changes++, live++;
00087 }
00088 }
00089 }
00090 }
00091
00092
00093 void makscr()
00094 {
00095 int curx, cury;
00096 char c;
00097
00098 wclear(info);
00099 wmove(info, 0, 0);
00100 wprintw(info, "Use arrow keys to move, space to place / erase, ^D to start", NULL);
00101 wrefresh(info);
00102 curx = cury = 1;
00103 wmove(mns, cury - 1, curx - 1);
00104 wrefresh(mns);
00105 noecho();
00106 for (;;) {
00107 c = wgetch(mns);
00108 if (c == '\004')
00109 break;
00110 else if (c == ' ') {
00111 if (present[cury][curx]) {
00112 --present[cury][curx];
00113 changes++;
00114 die++;
00115 mvwaddch(mns, cury, curx, ' ');
00116 } else {
00117 ++present[cury][curx];
00118 changes++;
00119 live++;
00120 mvwaddch(mns, cury, curx, '*');
00121 }
00122 } else if (c == '\033') {
00123 wgetch(mns);
00124 switch (wgetch(mns)) {
00125 case 'A': --cury; break;
00126 case 'B': ++cury; break;
00127 case 'C': ++curx; break;
00128 case 'D': --curx; break;
00129 default: break;
00130 }
00131 }
00132 if (cury > maxrow) cury = minrow;
00133 if (cury < minrow) cury = maxrow;
00134 if (curx > maxcol) curx = mincol;
00135 if (curx < mincol) curx = maxcol;
00136 wmove(mns, cury, curx);
00137 wrefresh(mns);
00138 }
00139 wclear(info);
00140 }
00141
00142
00143
00144
00145
00146 void update()
00147 {
00148 int howmany, w, x, y, z;
00149 changes = die = live = 0;
00150 for (j = 0; j < maxrow; j++) {
00151 for (k = 0; k < maxcol; k++) {
00152 w = j - 1;
00153 x = j + 1;
00154 y = k - 1;
00155 z = k + 1;
00156
00157 howmany = (past[w][y] + past[w][k] + past[w][z] +
00158 past[j][y] + past[j][z] + past[x][y] +
00159 past[x][k] + past[x][z]);
00160
00161 switch (howmany) {
00162 case 0:
00163 case 1:
00164 case 4:
00165 case 5:
00166 case 6:
00167 case 7:
00168 case 8:
00169 present[j][k] = 0;
00170 if (past[j][k]) changes++, die++;
00171 break;
00172 case 3:
00173 present[j][k] = 1;
00174 if (!past[j][k]) changes++, live++;
00175 break;
00176 default: break;
00177 }
00178 }
00179 }
00180 if (live == die)
00181 ++icnt;
00182 else
00183 icnt = 0;
00184
00185 if (icnt == REPSTOP) cleanup(0);
00186 }
00187
00188
00189 void print()
00190 {
00191
00192 if (pri) {
00193 wmove(info, 0, 0);
00194 total += changes;
00195 cycle++;
00196 wprintw(info, "Cycle %5d | %5d changes: %5d died + %5d born = %5u total changes", (char *) cycle, changes, die, live, total);
00197 wclrtoeol(info);
00198 }
00199 for (j = 1; j < maxrow; j++) {
00200 for (k = 1; k < maxcol; k++) {
00201 if (present[j][k] != past[j][k] && present[j][k] == 1) {
00202 wmove(mns, j, k);
00203 wprintw(mns, "*", NULL);
00204 } else if (present[j][k] != past[j][k] && present[j][k] == 0) {
00205 wmove(mns, j, k);
00206 wprintw(mns, " ", NULL);
00207 }
00208 }
00209 }
00210 if (pri) wrefresh(info);
00211 wrefresh(mns);
00212 }
00213
00214
00215 int main(ac, av)
00216 int ac;
00217 char *av[];
00218 {
00219 if (ac > 1) {
00220 for (j = 1; j < ac; j++) {
00221 switch (av[j][1]) {
00222 case 'd': ++draw; break;
00223 case 'p': ++pri; break;
00224 default:
00225 fprintf(stderr, "%s: usage: %s [-d] [-p]\n", av[0], av[0]);
00226 exit(1);
00227 }
00228 }
00229 }
00230
00231 initialize();
00232 if (draw) makscr();
00233
00234 for (;;) {
00235 print();
00236 for (j = 0; j < maxrow; j++) {
00237 for (k = 0; k < maxcol; k++) past[j][k] = present[j][k];
00238 }
00239 update();
00240 }
00241 }