0e6fb02182625c8b99a1db6c29e5d0cc45cb3553
[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 num_directions = 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 for (dir_i=1; dir_i <= num_directions; dir_i ++) {
99 direction = directions[dir_i];
100
101 xn = offsets[direction, "x"] + xi;
102 yn = offsets[direction, "y"] + yi;
103
104 if (xn > 0 && xn <= x && yn > 0 && yn <= y) {
105 neighbor_state = board[prev_gen_id, yn, xn];
106 live_neighbors += neighbor_state;
107 }
108 };
109
110 board[gen_id, yi, xi] = get_new_state(state, live_neighbors);
111 }
112 }
113 }
114 }
115
116
117 function set_delete_generation(board, gen_id) {
118 for (cell in board) {
119 if (match(cell, "^" gen_id SUBSEP)) {
120 delete board[cell]
121 }
122 }
123 }
124
125
126 function life() {
127 "stty size" | getline stty_size_out;
128 split(stty_size_out, stty_size);
129
130 x = stty_size[2];
131 y = stty_size[1] - 3; # Minus 1 row for each: border, border, cursor
132
133 gen_id = 0;
134 while (1) {
135 prev_gen_id = gen_id;
136 gen_id++;
137
138 set_generation(board, gen_id, y, x);
139 do_print_generation(board, gen_id, y, x);
140 set_delete_generation(board, prev_gen_id);
141 }
142 }
143
144
145 BEGIN {life()}
This page took 0.050724 seconds and 3 git commands to generate.