JSFiddle - React, Tailwind, and code Playground
HTML
<form name="f">
<div id="a">
<p>
<button type="button" name="b1">進む</button>
<button type="button" name="b2">止める</button>
<button type="button" name="b3">一つ進む</button>
<input type="text" name="g" size="5" readonly>世代
</p>
</div>
<div id="b">
<canvas id="c"></canvas>
</div>
<div id="d">
<button type="button" data-d="[[]]">クリア</button>
<button type="button" data-d="[[],[],[],[],[],[],[],[],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1]]">ダイハード</button>
<button type="button" data-d="[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[0,0,0,0,0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1]]">ドングリ</button>
<button type="button" data-d="[[],[0,0,1,0],[0,0,0,1],[0,1,1,1]]">グライダー</button>
<button type="button" data-d="[[],[0,1,0,0,1],[0,0,0,0,0,1],[0,1,0,0,0,1],[0,0,1,1,1,1]]">宇宙船(小)</button>
<button type="button" data-d="[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1]]">ペンタデカスロン</button>
<button type="button" data-d="[[],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],[0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1],[0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]]">グライダー・ガン</button>
<button type="button"...
JavaScript
var c = 10;
var w = 50;
var h = 50;
var t = 100;
var tid;
var g = 1;
var d = [];
for (var y = 0; y < h; ++y) {
d[y] = [];
for (var x = 0; x < w; ++x) {
d[y][x] = 0;
}
}
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
canvas.width = c * w;
canvas.height = c * h;
function draw(d, c, w, h, g, b) {
for (var y = 0; y < h; ++y) {
for (var x = 0; x < w; ++x) {
//全て描き直すと負荷が激しいため、変化のあった場所だけ描き直す
if (!(b && b[y] && (b[y][x] == d[y][x]))) {
ctx.fillStyle = (d[y][x]) ? '#003366' : '#eeeeff';
ctx.beginPath();
ctx.rect(x * c, y * c, c, c);
ctx.closePath();
ctx.fill();
}
}
}
document.f.g.value = g;
}
function calc(d, w, h) {
var e = [];
for (var y = 0; y < h; ++y) {
e[y] = [];
for (var x = 0; x < w; ++x) {
//生存、誕生以外は過疎、過密で死滅
e[y][x] = 0;
//周囲の個体数(上辺のさらに上は下辺、左辺のさらに左は右辺…のようにしている)
var k = d[(h + y - 1) % h][(w + x - 1) % w] + d[(h + y - 1) % h][(w + x + 0) % w] + d[(h + y - 1) % h][(w + x + 1) % w] + d[(h + y + 0) % h][(w + x - 1) % w] + d[(h + y + 0) % h][(w + x + 1) % w] + d[(h + y + 1) % h][(w + x - 1) % w] + d[(h + y + 1) % h][(w + x + 0) % w] + d[(h + y + 1) % h][(w + x + 1) % w];
if (d[y][x]) {
if ((k == 2) || (k == 3)) {
//生存
e[y][x] = 1;
}
} else {
if (k == 3) {
//誕生
e[y][x] = 1;
}
}
}
}
return e;
}
function tsugi() {
var b = d;
d = calc(b, w, h);
++g;
draw(d, c, w, h, g, b);
}
function susumu() {
if (!tid) {
tid = setInterval(tsugi, t);
}
}
function tomeru() {
clearInterval(tid);
tid = 0;
}
function komaokuri() {
tsugi();
}
function life(e) {
var rect =...