Commit | Line | Data |
---|---|---|
917c9b6f | 1 | #! /usr/bin/awk -f |
457f4070 SK |
2 | |
3 | ||
4 | function CHAR_BORDER() {return "-"} | |
5 | function CHAR_ALIVE() {return "o"} | |
6 | function CHAR_DEAD() {return " "} | |
7 | ||
8 | ||
3a20c476 | 9 | function get_random_state() { |
457f4070 SK |
10 | return int(2 * rand()) |
11 | } | |
12 | ||
13 | ||
b161e882 | 14 | function get_init_board(n) { |
457f4070 SK |
15 | board = ""; |
16 | ||
17 | for (i=1; i <= n; i++) { | |
3a20c476 | 18 | board = sprintf("%s%d", board, get_random_state()) |
457f4070 SK |
19 | }; |
20 | ||
21 | return board | |
22 | } | |
23 | ||
24 | ||
b161e882 | 25 | function get_char_of_state(state) { |
457f4070 SK |
26 | if (state == 1) { |
27 | return CHAR_ALIVE() | |
28 | } else if (state == 0) { | |
29 | return CHAR_DEAD() | |
30 | } | |
31 | } | |
32 | ||
33 | ||
24212f47 SK |
34 | function do_print_border(x) { |
35 | for (i=1; i <= x; i++) { | |
36 | printf CHAR_BORDER() | |
37 | }; | |
3a20c476 | 38 | |
24212f47 SK |
39 | } |
40 | ||
41 | ||
b161e882 SK |
42 | function do_print_board(x, n, board) { |
43 | do_print_border(x); | |
457f4070 SK |
44 | |
45 | for (i=1; i <= n; i++) { | |
b161e882 | 46 | printf "%s", get_char_of_state(substr(board, i, 1)); |
457f4070 SK |
47 | |
48 | if (i % x == 0) { | |
49 | printf "\n" | |
50 | } | |
51 | }; | |
52 | ||
3a20c476 | 53 | do_print_border(x) |
457f4070 SK |
54 | } |
55 | ||
56 | ||
b161e882 | 57 | function get_new_state(state, live_neighbors) { |
457f4070 SK |
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 | ||
b161e882 | 72 | function get_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) { | |
3a20c476 SK |
89 | neighbor_id = offsets[direction] + cell_id; |
90 | ||
91 | # ----------------------------------------------------------------- | |
92 | # Real neighbors within boundaries, ghosts beyond that! | |
93 | # ----------------------------------------------------------------- | |
94 | if ((neighbor_id >= 1) && (neighbor_id <= n)) { | |
95 | neighbor_state = substr(board, neighbor_id, 1) | |
96 | } else { | |
97 | neighbor_state = get_random_state() | |
98 | }; | |
99 | ||
100 | live_neighbors += neighbor_state | |
457f4070 SK |
101 | } |
102 | ||
b161e882 | 103 | new_cell_state = get_new_state(cell_state, live_neighbors); |
3a20c476 | 104 | new_board = sprintf("%s%d", new_board, new_cell_state) |
457f4070 SK |
105 | }; |
106 | ||
107 | return new_board | |
108 | } | |
109 | ||
110 | ||
111 | function life() { | |
112 | "stty size" | getline stty_size_out; | |
113 | split(stty_size_out, stty_size); | |
114 | ||
115 | x = stty_size[2]; | |
116 | y = stty_size[1] - 3; # Minus 1 char for each: border, border, cursor | |
117 | n = x * y; | |
118 | ||
b161e882 | 119 | board = get_init_board(n); |
457f4070 SK |
120 | |
121 | while (1) { | |
b161e882 | 122 | do_print_board(x, n, board); |
3a20c476 | 123 | board = get_new_generation(x, n, board) |
457f4070 SK |
124 | } |
125 | } | |
126 | ||
127 | ||
128 | BEGIN {life()} |