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 | ||
457f4070 | 72 | function new_generation(x, n, board) { |
7b9dc10b SK |
73 | offsets["N" ] = - x ; |
74 | offsets["NE"] = -(x - 1); | |
75 | offsets["E" ] = 1 ; | |
76 | offsets["SE"] = x + 1 ; | |
77 | offsets["S" ] = x ; | |
78 | offsets["SW"] = x - 1 ; | |
79 | offsets["W" ] = - 1 ; | |
80 | offsets["NW"] = -(x + 1); | |
457f4070 SK |
81 | |
82 | new_board = ""; | |
83 | ||
84 | for (cell_id=1; cell_id <= n; cell_id++) { | |
85 | cell_state = substr(board, cell_id, 1); | |
86 | live_neighbors = 0; | |
87 | ||
88 | for (direction in offsets) { | |
89 | neighbor = offsets[direction] + cell_id; | |
90 | ||
91 | # Make sure we're within limmits of the board | |
92 | if ( !(neighbor < 1) && !(neighbor > n)) { | |
93 | neighbor_state = substr(board, neighbor, 1); | |
94 | live_neighbors += neighbor_state; | |
95 | } | |
96 | } | |
97 | ||
98 | new_cell_state = new_state(cell_state, live_neighbors); | |
99 | new_board = sprintf("%s%d", new_board, new_cell_state); | |
100 | }; | |
101 | ||
102 | return new_board | |
103 | } | |
104 | ||
105 | ||
106 | function life() { | |
107 | "stty size" | getline stty_size_out; | |
108 | split(stty_size_out, stty_size); | |
109 | ||
110 | x = stty_size[2]; | |
111 | y = stty_size[1] - 3; # Minus 1 char for each: border, border, cursor | |
112 | n = x * y; | |
113 | ||
114 | board = init_board(n); | |
115 | ||
116 | while (1) { | |
117 | print_board(x, n, board); | |
118 | board = new_generation(x, n, board); | |
119 | } | |
120 | } | |
121 | ||
122 | ||
123 | BEGIN {life()} |