--- /dev/null
+#! /usr/bin/env awk -f
+
+
+function CHAR_BORDER() {return "-"}
+function CHAR_ALIVE() {return "o"}
+function CHAR_DEAD() {return " "}
+
+
+function init_cell() {
+ return int(2 * rand())
+}
+
+
+function init_board(n) {
+ board = "";
+
+ for (i=1; i <= n; i++) {
+ board = sprintf("%s%d", board, init_cell())
+ };
+
+ return board
+}
+
+
+function print_border(x) {
+ for (i=1; i <= x; i++) {
+ printf CHAR_BORDER()
+ };
+ print;
+}
+
+
+function char_of_state(state) {
+ if (state == 1) {
+ return CHAR_ALIVE()
+ } else if (state == 0) {
+ return CHAR_DEAD()
+ }
+}
+
+
+function print_board(x, n, board) {
+ print_border(x);
+
+ for (i=1; i <= n; i++) {
+ printf "%s", char_of_state(substr(board, i, 1));
+
+ if (i % x == 0) {
+ printf "\n"
+ }
+ };
+
+ print_border(x);
+}
+
+
+function new_state(state, live_neighbors) {
+ if (state == 1 && live_neighbors < 2) {
+ return 0
+ } else if (state == 1 && live_neighbors < 4) {
+ return 1
+ } else if (state == 1 && live_neighbors > 3) {
+ return 0
+ } else if (state == 0 && live_neighbors == 3) {
+ return 1
+ } else {
+ return state
+ }
+}
+
+
+function ensure_negative(n) {
+ if (n < 0) {
+ return n
+ } else {
+ return -n
+ }
+}
+
+
+function new_generation(x, n, board) {
+ offsets["N" ] = ensure_negative(x );
+ offsets["NE"] = ensure_negative(x - 1);
+ offsets["E" ] = 1 ;
+ offsets["SE"] = x + 1 ;
+ offsets["S" ] = x ;
+ offsets["SW"] = x - 1 ;
+ offsets["W" ] = - 1 ;
+ offsets["NW"] = ensure_negative(x + 1);
+
+ new_board = "";
+
+ for (cell_id=1; cell_id <= n; cell_id++) {
+ cell_state = substr(board, cell_id, 1);
+ live_neighbors = 0;
+
+ for (direction in offsets) {
+ neighbor = offsets[direction] + cell_id;
+
+ # Make sure we're within limmits of the board
+ if ( !(neighbor < 1) && !(neighbor > n)) {
+ neighbor_state = substr(board, neighbor, 1);
+ live_neighbors += neighbor_state;
+ }
+ }
+
+ new_cell_state = new_state(cell_state, live_neighbors);
+ new_board = sprintf("%s%d", new_board, new_cell_state);
+ };
+
+ return new_board
+}
+
+
+function life() {
+ "stty size" | getline stty_size_out;
+ split(stty_size_out, stty_size);
+
+ x = stty_size[2];
+ y = stty_size[1] - 3; # Minus 1 char for each: border, border, cursor
+ n = x * y;
+
+ board = init_board(n);
+
+ while (1) {
+ print_board(x, n, board);
+ board = new_generation(x, n, board);
+ }
+}
+
+
+BEGIN {life()}