X-Git-Url: https://git.wirehaze.ovh/lifeboot.git/blobdiff_plain/693fc5383745f0999d9fa5348c2a3d6ffc2f8e5e..a8cfbb9937178d02aa35816ac8607b2525ba7263:/prototype.c?ds=sidebyside diff --git a/prototype.c b/prototype.c index 405654e..83b9398 100644 --- a/prototype.c +++ b/prototype.c @@ -1,5 +1,6 @@ +#include #include -#include +#include #include #define COLS 80 @@ -8,41 +9,126 @@ #define DEAD ' ' #define ALIVE '#' -#define INIT_RATIO 10 +#define INIT_RATIO 4 -#define STR(x) _STR(x) +#define STR(x) _STR (x) #define _STR(x) #x -static void clearscr() { - printf("\e[1;1H\e[2J"); +static uint16_t xss; /* xs() state */ + +static uint16_t +xs () /* xorshift prng */ +{ + xss ^= (xss << 1); + xss ^= (xss >> 3); + xss ^= (xss << 10); + + return xss; +} + +static void +clearscr () +{ + printf ("\e[1;1H\e[2J"); } -static void print_row(char row[COLS]) { - printf("%." STR(COLS) "s\n", row); +static void +print_row (char row[COLS]) +{ + printf ("%." STR (COLS) "s\n", row); } -static void print_grid(char grid[COLS * ROWS]) { +static void +print_grid (char grid[COLS * ROWS]) +{ for (int i = 0; i < ROWS; i++) - print_row(grid + i * COLS); + print_row (grid + i * COLS); +} + +static void +init_grid (char grid[COLS * ROWS]) +{ + for (int i = 0; i < COLS * ROWS; i++) + { + if (xs () % INIT_RATIO) + grid[i] = DEAD; + else + grid[i] = ALIVE; + } +} + +static char +get_state (char grid[COLS * ROWS], int row, int col) +{ + if (row < 0 || row >= ROWS || col < 0 || col >= COLS) + return DEAD; + + return grid[row * COLS + col]; +} + +static int +alive_neighbours (char grid[COLS * ROWS], int idx) +{ + int row = idx / COLS; + int col = idx % COLS; + int neighbours = 0; + + for (int i = -1; i <= 1; i++) + for (int j = -1; j <= 1; j++) + if (get_state (grid, row + i, col + j) == ALIVE) + neighbours++; + + if (get_state (grid, row, col) == ALIVE) + neighbours--; + + return neighbours; } -static void init_grid(char grid[COLS * ROWS]) { - for (int i = 0; i < ROWS * COLS; i++) { - if (rand() % INIT_RATIO) - grid[i] = DEAD; - else - grid[i] = ALIVE; - } +static char +next_state (char grid[COLS * ROWS], int idx) +{ + int n = alive_neighbours (grid, idx); + + if (get_state (grid, idx / COLS, idx % COLS) == ALIVE) + { + if (n < 2 || n > 3) + return DEAD; + + return ALIVE; + } + + if (n == 3) + return ALIVE; + + return DEAD; +} + +static void +update_grid (char grid[COLS * ROWS]) +{ + char new[COLS * ROWS]; + + for (int i = 0; i < COLS * ROWS; i++) + new[i] = next_state (grid, i); + + memcpy (grid, new, COLS * ROWS); } -int main () { +int +main () +{ char grid[COLS * ROWS]; - srand(time(0)); - init_grid(grid); + xss = time (0); + init_grid (grid); - clearscr(); - print_grid(grid); + do + { + clearscr (); + print_grid (grid); + update_grid (grid); + } + while (getchar () != 'q'); return 0; }