下には大きめのライフゲームのフィールドを作ってみた。「RUN」を押して始めてみよう。また、マウスクリックやタップでもで生物を足したり消したりすることができるようになっているのでいろいろ試してみてほしい。
var canvas1 = document.getElementById(“canvas1”);
canvas1.addEventListener(‘click’, onClick, false);
var ctx1 = canvas1.getContext(“2d”);
var Timer;
var TimerVar=250;
var w=320;
var h=320;
var dw =10;
var dh =10;
var nw=w/dw;
var nh=h/dh;
var s0 = new Array(nh);
var s1 = new Array(nh);
for (i=0;i<nh;i++){
s0[i]=new Array(nw);
s1[i]=new Array(nw);
}
var pat = [[0,1,0,0,0,0,0],
[0,0,0,1,0,0,0],
[1,1,0,0,1,1,1]];
h_pat=3
w_pat=7
pat_y = 23
pat_x = 20
var pat2 = [[1,1,1],
[0,0,1],
[0,1,0]];
h_pat2=3
w_pat2=3
pat2_y = 20
pat2_x = 5
for(i=0;i<nh;i++){
for(j=0;j<nw;j++){
s0[i][j] = 0;
s1[i][j] = 0;
}
}
function Start()
{
if (document.f1.b1.value == "RUN")
{
document.f1.b1.value="STOP";
Timer = setInterval("Main()",TimerVar);
Main();
Show_field();
}
else
{
document.f1.b1.value="RUN";
Show_field();
clearInterval(Timer);
}
}
function Show_field()
{
ctx1.fillStyle="white";
ctx1.rect(0,0,w,h);
ctx1.fill();
for(i=0;i<nh;i++){
for(j=0;j<nw;j++){
ctx1.beginPath();
ctx1.lineWidth=1;
ctx1.strokeStyle="rgba(150,150,150,1)";
if(document.f1.b1.value=="RUN"){
ctx1.fillStyle="rgba(200,200,200,1)";
}else{
ctx1.fillStyle="rgba(255,255,255,1)";
}
if(s0[i][j]==1){
ctx1.fillStyle="rgba(50,255,50,1)";
}
ctx1.rect(j*dw,i*dh,dw-1,dh-1);
ctx1.fill();
ctx1.stroke();
ctx1.beginPath();
}
}
}
function Clear_all()
{
for(i=0;i<nh;i++){
for(j=0;j<nw;j++){
s0[i][j] = 0;
}
}
document.f1.b1.value=="RUN"
Show_field();
}
function Reset()
{
for(i=0;i<nh;i++){
for(j=0;j<nw;j++){
s0[i][j] = 0;
}
}
for(i=0;i<w_pat;i++){
for(j=0;j<h_pat;j++){
s0[j+pat_y][i+pat_x]=pat[j][i];
}
}
for(i=0;i<w_pat2;i++){
for(j=0;j<h_pat2;j++){
s0[j+pat2_y][i+pat2_x]=pat2[j][i];
}
}
if(document.f1.b1.value=="STOP"){
Start();
}else{
Show_field();
}
}
function onClick(e) {
var rect = e.target.getBoundingClientRect();
x = e.clientX – rect.left;
y = e.clientY – rect.top;
ix=Math.floor(x/dw);
iy=Math.floor(y/dh);
s0[iy][ix]=1-s0[iy][ix];
Show_field();
}
function Main(){
f_live=0;
for(i=1;i<nh-1;i++){
for(j=1;j<nw-1;j++){
im=i-1;
jm=j-1;
ip=i+1;
jp=j+1;
s=s0[im][jm]+s0[im][j]+s0[im][jp]+
s0[i ][jm] +s0[i ][jp]+
s0[ip][jm]+s0[ip][j]+s0[ip][jp];
if(s0[i][j]==0){
if(s==3){
s1[i][j]=1;
f_live=1;
}else{
s1[i][j]=0;
}
}else{
if(s==2 | s==3){
s1[i][j]=1;
f_live=1;
}else{
s1[i][j]=0;
}
}
}
}
for(i=0;i<nh;i++){
for(j=0;j<nw;j++){
s0[i][j] = s1[i][j];
}
}
Show_field();
if(f_live==0){
Start();
}
}
Reset();
例えば、CLEAR を押して消してから、下のようなパターンを入れてRUNを押してみよう。面白い動きがみられるので試してみよう。

Wikipedia でもいろいろなパターンが紹介されているよ。
さて、上記のパネルで始めに配置していたパターンは、「グライダー」と「どんぐり」という名前がついている。グライダーは斜めに飛んでいくパターンだ。個々の生物は動かないのに、パターンとして動くのが面白い。あたかも波のようなだ。ドングリは、小さいパターンにも関わらず、複雑に大きく広がっていくパターン。この配置では、増殖してグライダーを飲み込んでしまう。フィールドがもっと大きければもっと長く、安定するまでに5000世代以上もかかるという。

上の初期状態から始まれば、しばらくすると下のパターンで落ち着く。それぞれのパターンには名前がついているんだ。

例えば、邪魔が入らない限り動かないパターンとして、「ブロック」「蜂の巣」とか、「船」、「ローフ」、「池」なんかがある。
あと、動きながら決まったパターンを繰り返すものもいる。一番頻繁に登場するのが、上の「ブリンカー」ってやつだ。
さて、グライダーだけど、グライダーをどんどん作り出すパターンが存在する。その名も「グライダー銃」。残念ながら上のフィールドには収まりきらないので、(3)で紹介しよう。