added serialize fn to universe and refactored some
[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
32 this.blank = blank || 0;
33
34 this.rows = 50;
35 this.columns = 50;
36
37 var cellWidth = canvas.width / this.rows;
38 var cellHeight = canvas.height / this.columns;
39
40 for (var i = 0; i < this.rows; i++) {
41 var world = [];
42 var x = 0;
43 var y = i * cellHeight;
44 for (var ii = 0; ii < this.columns; ii++) {
45 world.push(new cell(x, y, cellWidth, cellHeight));
46 x += cellWidth;
47 if (this.blank) { world[ii].kill(); }
48 else { Math.random() > .5 ? world[ii].revive() : world[ii].kill(); }
49 }
50 this.population.push(world);
51 }
52
53 this.redraw = function() {
54 for (var i = 0; i < this.rows; i++) {
55 for (var ii = 0; ii < this.columns; ii++) {
56 if (this.population[i][ii].state == 1) {
57 this.population[i][ii].redraw();
58 }
59 }
60 }
61 }
62
63 this.serialize = function() {
64 var serial = '';
65 for (var i = 0; i < this.rows; i++) {
66 for (var ii = 0; ii < this.columns; ii++) {
67 serial += this.population[i][ii].state;
68 }
69 }
70 return serialize;
71 }
72 }
73
74 function tick(automaton) {
75 automaton.generation += 1;
76 var universe = automaton.population;
77 var newUniverse = [];
78 for (var i = 0; i < universe.length; i++) {
79 newUniverse[i] = [];
80 for (var ii = 0; ii < universe[i].length; ii++) {
81 var neighbors = (universe[i][ii+1] ? universe[i][ii+1].state : 0) +
82 (universe[i][ii-1] ? universe[i][ii-1].state : 0) +
83 (universe[i+1] ?
84 (universe[i+1][ii] ? universe[i+1][ii].state : 0) +
85 (universe[i+1][ii+1] ? universe[i+1][ii+1].state : 0) +
86 (universe[i+1][ii-1] ? universe[i+1][ii-1].state : 0)
87 : 0) +
88 (universe[i-1] ?
89 (universe[i-1][ii] ? universe[i-1][ii].state : 0) +
90 (universe[i-1][ii-1] ? universe[i-1][ii-1].state : 0) +
91 (universe[i-1][ii+1] ? universe[i-1][ii+1].state : 0)
92 : 0);
93 universe[i][ii].neighbors = neighbors;
94 if (universe[i][ii].state == 1) {
95 if (neighbors < 2 || neighbors > 3) {
96 newUniverse[i][ii] = 0;
97 } else {
98 newUniverse[i][ii] = 1;
99 }
100 } else {
101 newUniverse[i][ii] = (neighbors == 3 ? 1 : 0);
102 }
103 }
104 }
105 for (var i in newUniverse) {
106 for (var ii in newUniverse[i]) {
107 newUniverse[i][ii] ? universe[i][ii].revive() : universe[i][ii].kill();
108 }
109 }
110 $('#generation')[0].innerHTML = automaton.generation;
111 }
112
113 var automaton = new universe;
114 var tickID = 0;
115 var running = 0;
116
117 $('#controls #start-automaton').click(function(e){
118 tickID = setInterval(function(){tick(automaton)}, 100);
119 $('#controls #start-automaton').hide();
120 $('#controls #stop-automaton').show();
121 running = 1;
122 });
123
124 $('#controls #stop-automaton').click(function(e){
125 if (running) clearInterval(tickID);
126 $('#controls #stop-automaton').hide();
127 $('#controls #start-automaton').show();
128 running = 0;
129 });
130
131 $('#controls #reseed-automaton').click(function(e){
132 if (running) clearInterval(tickID);
133 $('#controls #stop-automaton').hide();
134 $('#controls #start-automaton').show();
135 automaton = new universe();
136 running = 0;
137 });
138
139 $('#controls #custom-seed-automaton').click(function(e){
140 if (running) clearInterval(tickID);
141 $('#controls #stop-automaton').hide();
142 $('#controls #start-automaton').show();
143 automaton = new universe(1);
144 running = 0;
145 });
146
147 $('#2d-automaton').click(function(e) {
148 if (!running) {
149 var x = e.pageX - $('#2d-automaton').offset().left;
150 var y = e.pageY - $('#2d-automaton').offset().top;
151 var row = Math.floor(y / cellHeight);
152 var column = Math.floor(x / cellWidth);
153 automaton.population[row][column].toggle();
154 }
155 });
156
157 });