A more readable list.
[cellular-automata.git] / 004 / 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_init_board(n) {
15 board = "";
16
17 for (i=1; i <= n; i++) {
18 board = sprintf("%s%d", board, get_random_state())
19 };
20
21 return board
22 }
23
24
25 function get_char_of_state(state) {
26 if (state == 1) {
27 return CHAR_ALIVE()
28 } else if (state == 0) {
29 return CHAR_DEAD()
30 }
31 }
32
33
34 function do_print_border(x) {
35 for (i=1; i <= x; i++) {
36 printf CHAR_BORDER()
37 };
38 print
39 }
40
41
42 function do_print_board(x, n, board) {
43 do_print_border(x);
44
45 for (i=1; i <= n; i++) {
46 printf "%s", get_char_of_state(substr(board, i, 1));
47
48 if (i % x == 0) {
49 printf "\n"
50 }
51 };
52
53 do_print_border(x)
54 }
55
56
57 function get_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 get_new_generation(x, n, board) {
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);
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_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
101 }
102
103 new_cell_state = get_new_state(cell_state, live_neighbors);
104 new_board = sprintf("%s%d", new_board, new_cell_state)
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
119 board = get_init_board(n);
120
121 while (1) {
122 do_print_board(x, n, board);
123 board = get_new_generation(x, n, board)
124 }
125 }
126
127
128 BEGIN {life()}
This page took 0.073457 seconds and 4 git commands to generate.