Last active
August 29, 2015 13:59
-
-
Save tokutoku3/10696591 to your computer and use it in GitHub Desktop.
canvasでライフゲーム
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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