f88df4644c7649dee8a6db526706deac967f377b
[cellular-automaton.git] / 2d.js
1 $(document).ready(function(){
2
3 var canvas = $('#2d-automaton')[0];
4 var c = canvas.getContext('2d');
5
6 var rows = 50;
7 var columns = 50;
8
9 var cellWidth = canvas.width / rows;
10 var cellHeight = canvas.height / columns;
11
12 function cell(x, y, h, l) {
13 this.x = x;
14 this.y = y;
15 this.h = h;
16 this.l = l;
17 this.state = 0;
18 this.kill = function() {
19 c.fillStyle = "rgb(255,255,255)";
20 c.fillRect(this.x, this.y, this.h, this.l);
21 this.state = 0;
22 }
23 this.revive = function() {
24 c.fillStyle = "rgb(0,0,0)";
25 c.fillRect(this.x, this.y, this.h, this.l);
26 this.state = 1;
27 }
28 this.toggle = function() {
29 this.state ? this.kill() : this.revive();
30 }
31 }
32
33 function universe(blank) {
34 this.population = [];
35 this.generation = 0;
36 var blank = blank || 0;
37
38 for (var i = 0; i < rows; i++) {
39 var world = [];
40 var x = 0;
41 var y = i * cellHeight;
42 for (var ii = 0; ii < columns; ii++) {
43 world.push(new cell(x, y, cellWidth, cellHeight));
44 x += cellWidth;
45 if (blank) { world[ii].kill(); }
46 else { Math.random() > .5 ? world[ii].revive() : world[ii].kill(); }
47 }
48 this.population.push(world);
49 }
50
51 this.highlight = function() {
52 for (var i = 0; i < rows; i++) {
53 for (var ii = 0; ii < columns; ii++) {
54 if (this.population[i][ii].state == 1) {
55 this.population[i][ii].highlight();
56 }
57 }
58 }
59 }
60
61 this.redraw = function() {
62 for (var i = 0; i < rows; i++) {
63 for (var ii = 0; ii < columns; ii++) {
64 if (this.population[i][ii].state == 1) {
65 this.population[i][ii].redraw();
66 }
67 }
68 }
69 }
70 }
71
72 function tick(automaton) {
73 automaton.generation += 1;
74 var universe = automaton.population;
75 var newUniverse = [];
76 for (var i = 0; i < universe.length; i++) {
77 newUniverse[i] = [];
78 for (var ii = 0; ii < universe[i].length; ii++) {
79 var neighbors = (universe[i][ii+1] ? universe[i][ii+1].state : 0) +
80 (universe[i][ii-1] ? universe[i][ii-1].state : 0) +
81 (universe[i+1] ?
82 (universe[i+1][ii] ? universe[i+1][ii].state : 0) +
83 (universe[i+1][ii+1] ? universe[i+1][ii+1].state : 0) +
84 (universe[i+1][ii-1] ? universe[i+1][ii-1].state : 0)
85 : 0) +
86 (universe[i-1] ?
87 (universe[i-1][ii] ? universe[i-1][ii].state : 0) +
88 (universe[i-1][ii-1] ? universe[i-1][ii-1].state : 0) +
89 (universe[i-1][ii+1] ? universe[i-1][ii+1].state : 0)
90 : 0);
91 universe[i][ii].neighbors = neighbors;
92 if (universe[i][ii].state == 1) {
93 if (neighbors < 2 || neighbors > 3) {
94 newUniverse[i][ii] = 0;
95 } else {
96 newUniverse[i][ii] = 1;
97 }
98 } else {
99 newUniverse[i][ii] = (neighbors == 3 ? 1 : 0);
100 }
101 }
102 }
103 for (var i in newUniverse) {
104 for (var ii in newUniverse[i]) {
105 newUniverse[i][ii] ? universe[i][ii].revive() : universe[i][ii].kill();
106 }
107 }
108 $('#generation')[0].innerHTML = automaton.generation;
109 }
110
111 var automaton = new universe;
112 var tickID = 0;
113 var running = 0;
114
115 $('#controls #start-automaton').click(function(e){
116 tickID = setInterval(function(){tick(automaton)}, 100);
117 $('#controls #start-automaton').hide();
118 $('#controls #stop-automaton').show();
119 running = 1;
120 });
121
122 $('#controls #stop-automaton').click(function(e){
123 if (running) clearInterval(tickID);
124 $('#controls #stop-automaton').hide();
125 $('#controls #start-automaton').show();
126 running = 0;
127 });
128
129 $('#controls #reseed-automaton').click(function(e){
130 if (running) clearInterval(tickID);
131 $('#controls #stop-automaton').hide();
132 $('#controls #start-automaton').show();
133 automaton = new universe();
134 running = 0;
135 });
136
137 $('#controls #custom-seed-automaton').click(function(e){
138 if (running) clearInterval(tickID);
139 $('#controls #stop-automaton').hide();
140 $('#controls #start-automaton').show();
141 automaton = new universe(1);
142 running = 0;
143 });
144
145 $('#2d-automaton').click(function(e) {
146 if (!running) {
147 var x = e.pageX - $('#2d-automaton').offset().left;
148 var y = e.pageY - $('#2d-automaton').offset().top;
149 var row = Math.floor(y / cellHeight);
150 var column = Math.floor(x / cellWidth);
151 automaton.population[row][column].toggle();
152 }
153 });
154
155 });