summaryrefslogtreecommitdiff
path: root/Source/Applications/Demos/GOL.cpp
blob: 804c9ae20e8e55772093c6d4a3792e1efe341b27 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <Binding/VirtualTerminal.class.h>
#include <Binding/Thread.class.h>
#include <String.class.h>
#include <Rand.ns.h>

int main(Vector<String> args) {
	if (!outvt.isBoxed()) {
		outvt << "Error : cannot display GOL on a non-boxed terminal.\n";
		return 1;
	}

	int h = outvt.height() - 1, w = outvt.width();

	bool *cells = new bool[w * h];
	bool *newcells = new bool[w * h];

	u32int delay = 100;

	for (u32int x = 0; x < w; x++) {
		for (u32int y = 0; y < h; y++) {
			cells[x * h + y] = false;
		}
	}

	char *tmp = new char[w * h + 1];

	bool run = true;
	while (run) {
		//Display cells
		for (u32int y = 0; y < h; y++) {
			for (u32int x = 0; x < w; x++) {
				if (cells[x * h + y]) {
					tmp[y * w + x] = '#';
				} else {
					tmp[y * w + x] = ' ';
				}
			}
		}
		outvt.moveCursor(0, 0);
		outvt << String(tmp, w*h) << "Press Ctrl+h for help";

		//Compute next generation
		for (u32int y = 0; y < h; y++) {
			for (u32int x = 0; x < w; x++) {
				u8int n = 0;
				for (u32int yy = y - 1; yy <= y + 1; yy++) {
					for (u32int xx = x - 1; xx <= x + 2; xx++) {
						if (xx < w and yy < h and cells[xx * h + yy]) n++;
					}
				}
				if (cells[x * h + y]) n--;
				if ((cells[x * h + y] and n == 2) or n == 3) {
					newcells[x * h + y] = true;
				} else {
					newcells[x * h + y] = false;
				}
			}
		}
		for (u32int x = 0; x < w; x++) {
			for (u32int y = 0; y < h; y++) {
				cells[x * h + y] = newcells[x * h + y];
			}
		}

		keypress_t kp = invt.getKeypress(false, false);
		while (kp.hascmd && (kp.modifiers & STATUS_CTRL)) {
			if (kp.character == WChar("c")) {
				run = false;
			} else if (kp.character == WChar("r")) {
				for (u32int i = 0; i < 20; i++) {
					u64int x = Rand::rand() * w / Rand::max();
					u64int y = Rand::rand() * h / Rand::max();
					cells[x * h + y] = true;
				}
			} else if (kp.character == WChar("R")) {
				for (u32int i = 0; i < h; i++) {
					cells[i] = true;
					cells[(2 * i) % (h - i)] = true;
					cells[(w * i) % (h * w - i)] = true;
					cells[(w * i) % (h * w - i) + w] = true;
				}
			} else if (kp.character == WChar("h")) {
				outvt << "\n\n** Melon's demo Game Of Life Simulator help :\n";
				outvt << " - ctrl+c : quit\n";
				outvt << " - ctrl+h : show this\n";
				outvt << " - ctrl+r : add some random cells\n";
				outvt << " - ctrl+R : add more cells, but not random\n\n";
				outvt << "Press any key to return to simultaor...";
				invt.getKeypress();
			}
			kp = invt.getKeypress(false, false);
		}

		Thread::get().sleep(100);
	}

	delete cells;
	delete newcells;
}