Life 5: AWK. Simulated 3D array.
[cellular-automata.git] / 005 / life.awk
1 #! /usr/bin/awk -f
2
3
4 function CHAR_BORDER() {return "-"}
5 function CHAR_ALIVE() {return "o"}
6 function CHAR_DEAD() {return " "}
7
8
9 function get_random_state() {
10 return int(2 * rand())
11 }
12
13
14 function get_char_of_state(state) {
15 if (state == 1) {
16 return CHAR_ALIVE()
17 } else if (state == 0) {
18 return CHAR_DEAD()
19 }
20 }
21
22
23 function do_print_border(x) {
24 for (i=1; i <= x; i++) {
25 printf CHAR_BORDER()
26 };
27 print
28 }
29
30
31 function do_print_generation(board, gen_id, y, x) {
32 do_print_border(x);
33
34 for (yi=1; yi <= y; yi++) {
35 for (xi=1; xi <= x; xi++) {
36 printf "%s", get_char_of_state(board[gen_id, yi, xi])
37 };
38
39 print
40 }
41
42 do_print_border(x);
43 }
44
45
46 function get_new_state(state, live_neighbors) {
47 if (state == 1 && live_neighbors < 2) {
48 return 0
49 } else if (state == 1 && live_neighbors < 4) {
50 return 1
51 } else if (state == 1 && live_neighbors > 3) {
52 return 0
53 } else if (state == 0 && live_neighbors == 3) {
54 return 1
55 } else {
56 return state
57 }
58 }
59
60
61 function set_generation(board, gen_id, y, x) {
62 split("N,NE,E,SE,S,SW,W,NW", directions, ",");
63
64 offsets["N" , "x"] = 0;
65 offsets["N" , "y"] = -1;
66
67 offsets["NE", "x"] = 1;
68 offsets["NE", "y"] = -1;
69
70 offsets["E" , "x"] = 1;
71 offsets["E" , "y"] = 0;
72
73 offsets["SE", "x"] = 1;
74 offsets["SE", "y"] = 1;
75
76 offsets["S" , "x"] = 0;
77 offsets["S" , "y"] = 1;
78
79 offsets["SW", "x"] = -1;
80 offsets["SW", "y"] = 1;
81
82 offsets["W" , "x"] = -1;
83 offsets["W" , "y"] = 0;
84
85 offsets["NW", "x"] = -1;
86 offsets["NW", "y"] = -1;
87
88 prev_gen_id = gen_id - 1;
89
90 for (yi=1; yi <= y; yi++) {
91 for (xi=1; xi <= x; xi++) {
92 if (gen_id == 1) {
93 board[gen_id, yi, xi] = get_random_state()
94 } else {
95 state = board[prev_gen_id, yi, xi];
96 live_neighbors = 0;
97
98 num_directions = length(directions);
99
100 for (dir_i=1; dir_i <= num_directions; dir_i ++) {
101 direction = directions[dir_i];
102
103 xn = offsets[direction, "x"] + xi;
104 yn = offsets[direction, "y"] + yi;
105
106 if (xn > 0 && xn <= x && yn > 0 && yn <= y) {
107 neighbor_state = board[prev_gen_id, yn, xn];
108 live_neighbors += neighbor_state;
109 }
110 };
111
112 board[gen_id, yi, xi] = get_new_state(state, live_neighbors);
113 }
114 }
115 }
116 }
117
118
119 function set_delete_generation(board, gen_id) {
120 for (cell in board) {
121 if (match(cell, "^" gen_id SUBSEP)) {
122 delete board[cell]
123 }
124 }
125 }
126
127
128 function life() {
129 "stty size" | getline stty_size_out;
130 split(stty_size_out, stty_size);
131
132 x = stty_size[2];
133 y = stty_size[1] - 3; # Minus 1 row for each: border, border, cursor
134
135 gen_id = 0;
136 while (1) {
137 prev_gen_id = gen_id;
138 gen_id++;
139
140 set_generation(board, gen_id, y, x);
141 do_print_generation(board, gen_id, y, x);
142 set_delete_generation(board, prev_gen_id);
143 }
144 }
145
146
147 BEGIN {life()}
This page took 0.056879 seconds and 4 git commands to generate.