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 =...