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