Why did I think I needed this again?
[cellular-automata.git] / 004 / life.awk
CommitLineData
457f4070
SK
1#! /usr/bin/env awk -f
2
3
4function CHAR_BORDER() {return "-"}
5function CHAR_ALIVE() {return "o"}
6function CHAR_DEAD() {return " "}
7
8
9function init_cell() {
10 return int(2 * rand())
11}
12
13
14function 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
25function print_border(x) {
26 for (i=1; i <= x; i++) {
27 printf CHAR_BORDER()
28 };
29 print;
30}
31
32
33function 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
42function 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
57function 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 72function 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
106function 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
123BEGIN {life()}
This page took 0.022703 seconds and 4 git commands to generate.