Conway's game of life with pbm files
P1 | |
6 6 | |
000000 | |
011000 | |
010000 | |
000010 | |
000110 | |
000000 |
P1 | |
16 9 | |
0000000000000000 | |
0000000000000000 | |
0000000000000000 | |
0001000000000000 | |
0101000000000000 | |
0011000000000000 | |
0000000000000000 | |
0000000000000000 | |
0000000000000000 |
P1 | |
48 27 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000100000000000000000 | |
000000000000000000000000000010100000000000000000 | |
000000000000000000110000001100000000000011000000 | |
000000000000000001000100001100000000000011000000 | |
000000110000000010000010001100000000000000000000 | |
000000110000000010001011000010100000000000000000 | |
000000000000000010000010000000100000000000000000 | |
000000000000000001000100000000000000000000000000 | |
000000000000000000110000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 | |
000000000000000000000000000000000000000000000000 |
#include <stdio.h> | |
#include <stdlib.h> | |
#define PBM_HEADER_FORMAT "P1\n%d %d\n" | |
#define DEAD '0' | |
#define ALIVE '1' | |
#define is_alive(X) ((X) == ALIVE) | |
#define mod(X, Y) (((Y) + (X)) % (Y)) | |
int | |
main(void) | |
{ | |
int height, width; | |
int i, j, io, jo, x, y; | |
int n; | |
void *swp; | |
if (scanf(PBM_HEADER_FORMAT, &width, &height) != 2) { | |
fprintf(stderr, "Input must be ASCII PBM\n"); | |
exit(1); | |
} | |
/* VLA trick */ | |
char (*prev)[width + 1] = calloc(height, sizeof(*prev)); | |
char (*state)[width + 1] = calloc(height, sizeof(*state)); | |
/* load initial game */ | |
if (fread(prev, sizeof(*prev), height, stdin) != height) { | |
fprintf(stderr, "Failed to read image data\n"); | |
exit(1); | |
} | |
for (i = 0; i < height; ++i) { | |
if (prev[i][width] != '\n') { | |
fprintf(stderr, "Row %d oversized\n", i); | |
exit(1); | |
} | |
state[i][width] = '\n'; | |
} | |
/* play game */ | |
#ifdef DURATION | |
for (int _time = 0; _time < DURATION; ++_time) { | |
#else | |
while (1) { | |
#endif | |
printf(PBM_HEADER_FORMAT, width, height); | |
fwrite(prev, sizeof(*prev), height, stdout); | |
for (i = 0; i < height; ++i) { | |
for (j = 0; j < width; ++j) { | |
n = 0; | |
for (io = -1; io < 2; ++io) { | |
for (jo = -1; jo < 2; ++jo) { | |
if (jo || io) { | |
y = mod(i + io, height); | |
x = mod(j + jo, width); | |
n += prev[y][x] == '1'; | |
} | |
} | |
} | |
if (is_alive(prev[i][j])) { | |
if (n == 2 || n == 3) { | |
state[i][j] = ALIVE; | |
} else { | |
state[i][j] = DEAD; | |
} | |
} else { | |
if (n == 3) { | |
state[i][j] = ALIVE; | |
} else { | |
state[i][j] = DEAD; | |
} | |
} | |
} | |
} | |
swp = prev; | |
prev = state; | |
state = swp; | |
} | |
return 0; | |
} |
CC = gcc | |
CFLAGS = -O3 -std=c99 | |
.PHONY: test | |
test: life | |
./life < gosper.pbm | mpv --no-correct-pts --fps=20 --scale=oversample - | |
.PHONY: time | |
time: life-limited | |
time ./$< < pulsar.pbm > /dev/null | |
life: life.c | |
$(CC) $(CFLAGS) -o $@ $< | |
life-limited: life.c | |
$(CC) $(CFLAGS) -DDURATION=1000000 -o $@ $< | |
.PHONY: clean | |
clean: | |
rm -f life life-limited |
P1 | |
17 17 | |
00000000000000000 | |
00000000000000000 | |
00001110001110000 | |
00000000000000000 | |
00100001010000100 | |
00100001010000100 | |
00100001010000100 | |
00001110001110000 | |
00000000000000000 | |
00001110001110000 | |
00100001010000100 | |
00100001010000100 | |
00100001010000100 | |
00000000000000000 | |
00001110001110000 | |
00000000000000000 | |
00000000000000000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment