// From http://rosettacode.org/wiki/Conway%27s_Game_of_Life#C #include #include #include #define for_x for (int x = 0; x < w; x++) #define for_y for (int y = 0; y < h; y++) #define for_xy for_x for_y void show(void *u, int w, int h) { int (*univ)[w] = u; for_x printf("-"); printf("\n"); for_y { for_x printf(univ[y][x] ? "[]" : " "); printf("\n"); } for_x printf("-"); printf("\n"); fflush(stdout); } void evolve(void *u, int w, int h) { unsigned (*univ)[w] = u; unsigned new[h][w]; for_y for_x { int n = 0; for (int y1 = y - 1; y1 <= y + 1; y1++) for (int x1 = x - 1; x1 <= x + 1; x1++) if (univ[(y1 + h) % h][(x1 + w) % w]) n++; if (univ[y][x]) n--; new[y][x] = (n == 3 || (n == 2 && univ[y][x])); } for_y for_x univ[y][x] = new[y][x]; } void nudge(void *u, int w, int h) { unsigned (*univ)[w] = u; int sum = 0; for_xy sum += univ[y][x]; while (sum < (w*h)/8) { int x = sum & (w-1); int y = (sum*sum) & (h-1); univ[y][x] = 1; sum++; } } void game(int w, int h, int i) { unsigned univ[h][w]; //for_xy univ[y][x] = rand() < RAND_MAX / 10 ? 1 : 0; int acc = 0; // nonrandom generation, for benchmarking for_xy { acc += (x*17) % (y*3 + 1); univ[y][x] = acc & 1; } while (i != 0) { //show(univ, w, h); evolve(univ, w, h); if (i > 0) { i--; nudge(univ, w, h); // keep it interesting for benchmark } else { usleep(20000); show(univ, w, h); } } show(univ, w, h); } int main(int argc, char **argv) { int w, h, i; int arg = argc > 1 ? argv[1][0] - '0' : 3; switch(arg) { case 0: return 0; break; case 1: w = h = 32; i = 2500; break; case 2: w = h = 32; i = 13000; break; case 3: w = h = 32; i = 24000; break; case 4: w = h = 32; i = 5*24000; break; case 5: w = h = 32; i = 10*24000; break; default: printf("error: %d\\n", arg); return -1; } printf("life: %d,%d,%d,%d\n", arg, w, h, i); game(w, h, i); return 0; }