-let board_print = (b : Board) : void => {
- board_print_border(b);
- let rows = b.length;
- let columns = b[0].length;
- for (let r = 0; r < rows; r++) {
- process.stdout.write("|");
- for (let k = 0; k < columns; k++) {
- let state = b[r][k];
- let state_string = state_to_string(state);
- process.stdout.write(state_string);
+namespace Life {
+ namespace State {
+ export type T = "Dead" | "Alive";
+
+ export const of_integer = (i : number) : T => {
+ switch (i)
+ { case 0 : return "Dead"
+ ; case 1 : return "Alive"
+ ; default: throw new RangeError("No known State for integer: " + i)
+ }
+ };
+
+ export const to_string = (t : T) : string => {
+ switch (t)
+ { case "Dead" : return " "
+ ; case "Alive": return "o"
+ ; default : throw new TypeError("Illegal member of Life.State.T: " + t)
+ }
+ };
+
+ export const is_alive = (t : T) : boolean => {
+ switch (t)
+ { case "Dead" : return false
+ ; case "Alive": return true
+ ; default : throw new TypeError("Illegal member of Life.State.T: " + t)
+ }
+ };
+
+ export const next = (t : T, neighbors_alive : number) : T => {
+ const is_cell_alive = is_alive(t);
+ if (is_cell_alive && neighbors_alive < 2) {
+ return "Dead"
+ } else if (is_cell_alive && neighbors_alive < 4) {
+ return "Alive"
+ } else if (is_cell_alive && neighbors_alive > 3) {
+ return "Dead"
+ } else if (!is_cell_alive && neighbors_alive === 3) {
+ return "Alive"
+ } else {
+ return t
+ }