#! /usr/bin/awk -f function CHAR_BORDER() {return "-"} function CHAR_ALIVE() {return "o"} function CHAR_DEAD() {return " "} function get_random_state() { return int(2 * rand()) } function get_char_of_state(state) { if (state == 1) { return CHAR_ALIVE() } else if (state == 0) { return CHAR_DEAD() } } function do_print_border(x) { for (i=1; i <= x; i++) { printf CHAR_BORDER() }; print } function do_print_generation(board, gen_id, y, x) { do_print_border(x); for (yi=1; yi <= y; yi++) { for (xi=1; xi <= x; xi++) { printf "%s", get_char_of_state(board[gen_id, yi, xi]) }; print } do_print_border(x); } function get_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 set_generation(board, gen_id, y, x) { split("N,NE,E,SE,S,SW,W,NW", directions, ","); offsets["N" , "x"] = 0; offsets["N" , "y"] = -1; offsets["NE", "x"] = 1; offsets["NE", "y"] = -1; offsets["E" , "x"] = 1; offsets["E" , "y"] = 0; offsets["SE", "x"] = 1; offsets["SE", "y"] = 1; offsets["S" , "x"] = 0; offsets["S" , "y"] = 1; offsets["SW", "x"] = -1; offsets["SW", "y"] = 1; offsets["W" , "x"] = -1; offsets["W" , "y"] = 0; offsets["NW", "x"] = -1; offsets["NW", "y"] = -1; prev_gen_id = gen_id - 1; for (yi=1; yi <= y; yi++) { for (xi=1; xi <= x; xi++) { if (gen_id == 1) { board[gen_id, yi, xi] = get_random_state() } else { state = board[prev_gen_id, yi, xi]; live_neighbors = 0; num_directions = length(directions); for (dir_i=1; dir_i <= num_directions; dir_i ++) { direction = directions[dir_i]; xn = offsets[direction, "x"] + xi; yn = offsets[direction, "y"] + yi; if (xn > 0 && xn <= x && yn > 0 && yn <= y) { neighbor_state = board[prev_gen_id, yn, xn]; live_neighbors += neighbor_state; } }; board[gen_id, yi, xi] = get_new_state(state, live_neighbors); } } } } function set_delete_generation(board, gen_id) { for (cell in board) { if (match(cell, "^" gen_id SUBSEP)) { delete board[cell] } } } 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 row for each: border, border, cursor gen_id = 0; while (1) { prev_gen_id = gen_id; gen_id++; set_generation(board, gen_id, y, x); do_print_generation(board, gen_id, y, x); set_delete_generation(board, prev_gen_id); } } BEGIN {life()}