Commit | Line | Data |
---|---|---|
457f4070 SK |
1 | #! /usr/bin/env awk -f |
2 | ||
3 | ||
4 | function CHAR_BORDER() {return "-"} | |
5 | function CHAR_ALIVE() {return "o"} | |
6 | function CHAR_DEAD() {return " "} | |
7 | ||
8 | ||
9 | function init_cell() { | |
10 | return int(2 * rand()) | |
11 | } | |
12 | ||
13 | ||
14 | function init_board(n) { | |
15 | board = ""; | |
16 | ||
17 | for (i=1; i <= n; i++) { | |
18 | board = sprintf("%s%d", board, init_cell()) | |
19 | }; | |
20 | ||
21 | return board | |
22 | } | |
23 | ||
24 | ||
25 | function print_border(x) { | |
26 | for (i=1; i <= x; i++) { | |
27 | printf CHAR_BORDER() | |
28 | }; | |
29 | print; | |
30 | } | |
31 | ||
32 | ||
33 | function char_of_state(state) { | |
34 | if (state == 1) { | |
35 | return CHAR_ALIVE() | |
36 | } else if (state == 0) { | |
37 | return CHAR_DEAD() | |
38 | } | |
39 | } | |
40 | ||
41 | ||
42 | function print_board(x, n, board) { | |
43 | print_border(x); | |
44 | ||
45 | for (i=1; i <= n; i++) { | |
46 | printf "%s", char_of_state(substr(board, i, 1)); | |
47 | ||
48 | if (i % x == 0) { | |
49 | printf "\n" | |
50 | } | |
51 | }; | |
52 | ||
53 | print_border(x); | |
54 | } | |
55 | ||
56 | ||
57 | function new_state(state, live_neighbors) { | |
58 | if (state == 1 && live_neighbors < 2) { | |
59 | return 0 | |
60 | } else if (state == 1 && live_neighbors < 4) { | |
61 | return 1 | |
62 | } else if (state == 1 && live_neighbors > 3) { | |
63 | return 0 | |
64 | } else if (state == 0 && live_neighbors == 3) { | |
65 | return 1 | |
66 | } else { | |
67 | return state | |
68 | } | |
69 | } | |
70 | ||
71 | ||
72 | function ensure_negative(n) { | |
73 | if (n < 0) { | |
74 | return n | |
75 | } else { | |
76 | return -n | |
77 | } | |
78 | } | |
79 | ||
80 | ||
81 | function new_generation(x, n, board) { | |
82 | offsets["N" ] = ensure_negative(x ); | |
83 | offsets["NE"] = ensure_negative(x - 1); | |
84 | offsets["E" ] = 1 ; | |
85 | offsets["SE"] = x + 1 ; | |
86 | offsets["S" ] = x ; | |
87 | offsets["SW"] = x - 1 ; | |
88 | offsets["W" ] = - 1 ; | |
89 | offsets["NW"] = ensure_negative(x + 1); | |
90 | ||
91 | new_board = ""; | |
92 | ||
93 | for (cell_id=1; cell_id <= n; cell_id++) { | |
94 | cell_state = substr(board, cell_id, 1); | |
95 | live_neighbors = 0; | |
96 | ||
97 | for (direction in offsets) { | |
98 | neighbor = offsets[direction] + cell_id; | |
99 | ||
100 | # Make sure we're within limmits of the board | |
101 | if ( !(neighbor < 1) && !(neighbor > n)) { | |
102 | neighbor_state = substr(board, neighbor, 1); | |
103 | live_neighbors += neighbor_state; | |
104 | } | |
105 | } | |
106 | ||
107 | new_cell_state = new_state(cell_state, live_neighbors); | |
108 | new_board = sprintf("%s%d", new_board, new_cell_state); | |
109 | }; | |
110 | ||
111 | return new_board | |
112 | } | |
113 | ||
114 | ||
115 | function life() { | |
116 | "stty size" | getline stty_size_out; | |
117 | split(stty_size_out, stty_size); | |
118 | ||
119 | x = stty_size[2]; | |
120 | y = stty_size[1] - 3; # Minus 1 char for each: border, border, cursor | |
121 | n = x * y; | |
122 | ||
123 | board = init_board(n); | |
124 | ||
125 | while (1) { | |
126 | print_board(x, n, board); | |
127 | board = new_generation(x, n, board); | |
128 | } | |
129 | } | |
130 | ||
131 | ||
132 | BEGIN {life()} |