ライフゲーム
説明なし。
デモ
プログラム
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ライフゲーム</title>
<style>
</style>
<script>
window.onload = function() {
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 = e.target.getBoundingClientRect();
var x = Math.floor((e.clientX - rect.left) / c);
var y = Math.floor((e.clientY - rect.top) / c);
d[y][x] = d[y][x] ? 0 : 1;
draw(d, c, w, h, g);
}
function pattern(e) {
var p = JSON.parse(e.target.dataset.d);
d = [];
for (var y = 0; y < h; ++y) {
d[y] = [];
for (var x = 0; x < w; ++x) {
d[y][x] = (p && p[y] && p[y][x] ? 1 : 0);
}
}
g = 1;
draw(d, c, w, h, g);
}
document.f.b1.addEventListener('click', susumu);
document.f.b2.addEventListener('click', tomeru);
document.f.b3.addEventListener('click', komaokuri);
document.getElementById('c').addEventListener('click', life);
for (var i = 0; i < document.getElementById('d').children.length; ++i) {
document.getElementById('d').children[i].addEventListener('click', pattern);
}
draw(d, c, w, h, g);
}
</script>
</head>
<body>
<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,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,1,0,0],[0,0,0,0,1,1],[0,0,1,1,0,0],[0,0,0,0,1,0]]">時計</button>
<button type="button" data-d="[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[0,0,0,0,0,0,0,0,0,0,1,1,1,1,1]]">-</button>
</div>
</form>
</body>
</html>
解説
(追記予定)