Skip to content

Instantly share code, notes, and snippets.

@louisswarren

louisswarren/Makefile

Last active Aug 12, 2020
Embed
What would you like to do?
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
You can’t perform that action at this time.