Skip to content

Instantly share code, notes, and snippets.

@tokutoku3
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tokutoku3/10696591 to your computer and use it in GitHub Desktop.
Save tokutoku3/10696591 to your computer and use it in GitHub Desktop.
canvasでライフゲーム
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lifegame</title>
<style>
body { background-color: black; }
.contents { width: 100%; text-align: center; }
</style>
</head>
<body>
<div class="contents">
<canvas id="world"></canvas>
</div>
<script>
// canvasの初期化
var canvas = document.getElementById("world");
var ctx = canvas.getContext("2d");
canvas.width = canvas.height = 400;
var SCREEN_SIZE = 100; // 縦横のマス数
// 画面の初期化
var world = new Array(SCREEN_SIZE);
for (var i = 0; i < SCREEN_SIZE; i++) {
world[i] = new Array(SCREEN_SIZE);
for (var j = 0; j < SCREEN_SIZE; j++) {
world[i][j] = new Cell(j, i, checkNeighbors(j, i));
// ランダムで生きているセルを生成する
if (Math.random() * 100 < 20) {
world[i][j].isAlive = true;
}
}
}
setInterval(simulate, 200);
function simulate () {
// セルの描画と、次世代のセルの状態を計算
for (var i = 0; i < SCREEN_SIZE; i++) {
for (var j = 0; j < SCREEN_SIZE; j++) {
world[i][j].draw();
world[i][j].nextAge();
}
}
// セルの状態を次世代の状態に更新
for (var i = 0; i < SCREEN_SIZE; i++) {
for (var j = 0; j < SCREEN_SIZE; j++) {
world[i][j].step();
}
}
};
// 周囲8マスにいくつセルがあるかカウントして返す
function checkNeighbors (x, y) {
var neighbors = new Array(3);
for (var i = 0; i < neighbors.length; i++) {
neighbors[i] = new Array(3);
for (var j = 0; j < neighbors[i].length; j++) {
if ((x == 0 && j == 0) || (x == SCREEN_SIZE-1 && j == 2)) {
neighbors[i][j] = false;
} else if ((y == 0 && i == 0) || (y == SCREEN_SIZE-1 && i == 2)) {
neighbors[i][j] = false;
} else {
neighbors[i][j] = true;
}
}
}
return neighbors;
};
// Cellクラス
function Cell (x, y, neighbors) {
var x = x,
y = y,
neighbors = neighbors,
isAlive = false,
next = false;
// 次世代の状態を計算
function nextAge () {
var cnt = 0;
// 隣接セルの死活チェック
for (var i = 0, l = neighbors.length; i < l; i++) {
for (var j = 0, l = neighbors[i].length; j < l; j++) {
if (neighbors[i][j] && world[y+i-1][x+j-1].isAlive) {
if (!(i == 1 && j == 1)) {
cnt++;
}
}
}
}
if (this.isAlive) {
if (cnt <= 1) {
underPopulation();
} else if (cnt <= 3) {
live();
} else {
overcrowding();
}
} else {
if (cnt == 3) {
reproduction();
}
}
};
// 過疎
function underPopulation () {
next = false;
};
// 生存
function live () {
next = true;
};
// 過密
function overcrowding () {
next = false;
};
// 誕生
function reproduction () {
next = true;
};
// 画面に描画
function draw () {
var style = (this.isAlive) ? "rgba(0, 200, 20, .6)" : "black";
ctx.fillStyle = style;
ctx.fillRect(x*4, y*4, 4, 4);
};
 // 次世代の状態を現在の状態として更新
function step () {
this.isAlive = next;
};
return {
neighbors: neighbors,
isAlive: isAlive,
nextAge: nextAge,
draw: draw,
step: step
}
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment