Meet the new twist in the old Game Of Life. To start/pause animation hit the spacebar. To setup the battlefield use the keyboard arrows.
var e=100,h=0.4,k,q,r,s,t=["#5E6D70","#FF6600","#1B1D1E"],u=!1;function x(){var g=0,f=1,d;k=Math.ceil(a.width/e);q=Math.ceil(a.height/k);r=[];for(s=[];g<e;g++)for(r[g]=[],s[g]=[],g>e/2-1&&(f=2),d=0;d<q;d++){r[g][d]=Math.random()>h?0:f;s[g][d]=0;var l=g*k,m=d*k;c.fillStyle=t[r[g][d]];c.fillRect(l,m,k,k)}}b.onkeyup=function(g){switch(g.keyCode){case 32:y();break;case 39:u||(e+=6,x());break;case 37:u||(e-=6,x());break;case 38:u||(h+=0.02,x());break;case 40:u||(h-=0.02,x())}};x();
function y(){function g(){for(var f=0,d;f<e;f++)for(d=0;d<q;d++){for(var l=0>f-1?e-1:f-1,m=f+1>e-1?0:f+1,n=0>d-1?q-1:d-1,p=d+1>q-1?0:d+1,l=[r[l][n],r[l][d],r[l][p],r[f][n],r[f][p],r[m][n],r[m][d],r[m][p]],v=p=n=m=0,w=void 0;8>v;v++)l[v]?1===l[v]?n++:p++:m++;w=n+p;s[f][d]=r[f][d]?2>w||3<w?0:r[f][d]:3!==w?0:p>n?2:n>p?1:Math.floor(Math.random()+0.5);l=f*k;m=d*k;c.fillStyle=t[s[f][d]];c.fillRect(l,m,k,k)}s=[r,r=s][0];u&&requestAnimationFrame(g)}(u=!u)&&requestAnimationFrame(g)};
dmFyIGU9MTAwLGg9MC40LGsscSxyLHMsdD1bIiM1RTZENzAiLCIjRkY2NjAwIiwiIzFCMUQxRSJdLHU9ITE7ZnVuY3Rpb24geCgpe3ZhciBnPTAsZj0xLGQ7az1NYXRoLmNlaWwoYS53aWR0aC9lKTtxPU1hdGguY2VpbChhLmhlaWdodC9rKTtyPVtdO2ZvcihzPVtdO2c8ZTtnKyspZm9yKHJbZ109W10sc1tnXT1bXSxnPmUvMi0xJiYoZj0yKSxkPTA7ZDxxO2QrKyl7cltnXVtkXT1NYXRoLnJhbmRvbSgpPmg/MDpmO3NbZ11bZF09MDt2YXIgbD1nKmssbT1kKms7Yy5maWxsU3R5bGU9dFtyW2ddW2RdXTtjLmZpbGxSZWN0KGwsbSxrLGspfX1iLm9ua2V5dXA9ZnVuY3Rpb24oZyl7c3dpdGNoKGcua2V5Q29kZSl7Y2FzZSAzMjp5KCk7YnJlYWs7Y2FzZSAzOTp1fHwoZSs9Nix4KCkpO2JyZWFrO2Nhc2UgMzc6dXx8KGUtPTYseCgpKTticmVhaztjYXNlIDM4OnV8fChoKz0wLjAyLHgoKSk7YnJlYWs7Y2FzZSA0MDp1fHwoaC09MC4wMix4KCkpfX07eCgpOw0KZnVuY3Rpb24geSgpe2Z1bmN0aW9uIGcoKXtmb3IodmFyIGY9MCxkO2Y8ZTtmKyspZm9yKGQ9MDtkPHE7ZCsrKXtmb3IodmFyIGw9MD5mLTE/ZS0xOmYtMSxtPWYrMT5lLTE/MDpmKzEsbj0wPmQtMT9xLTE6ZC0xLHA9ZCsxPnEtMT8wOmQrMSxsPVtyW2xdW25dLHJbbF1bZF0scltsXVtwXSxyW2ZdW25dLHJbZl1bcF0sclttXVtuXSxyW21dW2RdLHJbbV1bcF1dLHY9cD1uPW09MCx3PXZvaWQgMDs4PnY7disrKWxbdl0/MT09PWxbdl0/bisrOnArKzptKys7dz1uK3A7c1tmXVtkXT1yW2ZdW2RdPzI+d3x8Mzx3PzA6cltmXVtkXTozIT09dz8wOnA+bj8yOm4+cD8xOk1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSswLjUpO2w9ZiprO209ZCprO2MuZmlsbFN0eWxlPXRbc1tmXVtkXV07Yy5maWxsUmVjdChsLG0sayxrKX1zPVtyLHI9c11bMF07dSYmcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGcpfSh1PSF1KSYmcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGcpfTs=
var NW = 100, // initial number of columns
P = 0.4, // density of the population
S, // cell's size
NH, // number of rows
C, // array to keep state of each cell
N, // array to keep state of each cell
CLRS = ["#5E6D70", "#FF6600","#1B1D1E"],
AN = false; // mark that animation's on
function init() {
var i = 0,
t = 1, //"tribes" are represented by "ones" and "twos"
j;
S = Math.ceil(a.width/NW);
NH = Math.ceil(a.height/S);
C = [];
N = [];
for ( ; i<NW; i++ ) {
C[i] = [];
N[i] = [];
if ( i > NW/2-1 ) { t = 2; } // next half for another tribe
for ( j = 0; j<NH; j++ ) {
C[i][j] = ( Math.random() > P) ? 0 : t;
N[i][j] = 0;
drawCell(i*S, j*S, C[i][j]);
}
}
}
b.onkeyup = function(e) {
switch (e.keyCode) {
case 32: showMustGoOn(); break;
case 39: if ( !AN ) { NW+=6; init(); }; break;
case 37: if ( !AN ) { NW-=6; init(); }; break;
case 38: if ( !AN ) { P+=0.02; init(); }; break;
case 40: if ( !AN ) { P-=0.02; init(); }; break;
}
};
init();
function drawCell(x, y, t) {
c.fillStyle = CLRS[t];
c.fillRect(x, y, S, S);
}
function showMustGoOn() {
AN = !AN;
if ( AN ) { requestAnimationFrame(generation); }
function generation() {
var m = 0, n;
for ( ; m<NW; m++ ) {
for ( n = 0; n<NH; n++ ) {
N[m][n] = calcState(m, n);
drawCell(m*S, n*S, N[m][n]);
}
}
N = [C, C = N][0]; // swap the arrays
if ( AN ) { requestAnimationFrame(generation); }
}
}
function calcState(i,j) {
// The battlefield essentially is a torus.
var mi = ( i-1 < 0 ) ? NW-1 : i-1,
pi = ( i+1 > NW-1 ) ? 0 : i+1,
mj = ( j-1 < 0 ) ? NH-1 : j-1,
pj = ( j+1 > NH-1 ) ? 0 : j+1,
// all the neighbours are welcome to the special array
neighbours = [
C[mi][mj],
C[mi][j],
C[mi][pj],
C[i][mj],
C[i][pj],
C[pi][mj],
C[pi][j],
C[pi][pj]
],
zerro = 0, ones = 0, twos = 0, z = 0, alive;
for ( ; z<8; z++ ) {
if ( neighbours[z] ) {
if ( neighbours[z]===1 ) {
ones++;
}else {
twos++;
}
}else {
zerro++;
}
}
alive = ones + twos;
// usual rules of the Conway's Game Of Life
if ( C[i][j] ) {
return ( alive<2 || alive>3 ) ? 0 : C[i][j];
}
//but if the dead cell was made to came to life, it appears as a member of the predominant (in the neighbourhood) tribe
return ( alive!==3 ) ? 0 : ( twos > ones ) ? 2 : ( ones > twos ) ? 1 : (Math.floor(Math.random()+0.5));
}