A CodePen by Pawel_Miech. Conway's Game Of Life - "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.[1]
The "game" is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Lif…
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
<body> | |
<div> | |
<h3> Conway's Game Of Life</h3> | |
<h4>Click on squares to bring them into life </h4> | |
Choose the size of cells: | |
<div><input type="range" id="setSize" name="setSize" min="5" max="120" step="5"/></div> | |
<div> | |
<input type="button" id="startGame" value="Start Game"/> | |
<input type="button" id="killLife" value="Stop Life"/> | |
<input type="button" id="clearLife" value="Clear Life"/> | |
</div> | |
<canvas id="canvas"></canvas> | |
</div> | |
</body> |
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
var canvas = document.getElementById("canvas"); | |
canvas.width = 500; | |
canvas.height = 500; | |
var button = document.getElementById("startGame"); | |
var sizer = document.getElementById("setSize"); | |
var kill = document.getElementById("killLife"); | |
var clear = document.getElementById("clearLife"); | |
var cx = canvas.getContext("2d"); | |
var size = 40; | |
var color = "#C0C0C0"; | |
var interval; | |
function Square(x, y, size, context, color, state) { | |
this.x = x; | |
this.y = y; | |
this.size = size; | |
this.cx = context; | |
this.color = color; | |
this.state = state; | |
} | |
Square.prototype = { | |
constructor: Square, | |
draw: function () { | |
this.cx.strokeStyle = "#000"; | |
this.cx.clearRect(this.x,this.y,this.size,this.size); | |
this.cx.strokeRect(this.x, this.y, this.size, this.size); | |
}, | |
markRed: function () { | |
this.cx.fillStyle = "#000"; | |
this.cx.fillRect(this.x, this.y, this.size, this.size); | |
}, | |
switchState: function () { | |
if (this.state == 0) { | |
//make alive when dead | |
this.state = 1; | |
this.markRed(); | |
} else if (this.state == 1) { | |
//kill if alive | |
this.state = 0; | |
this.draw(); | |
} | |
} | |
} | |
function Game(deadCells, aliveCells) { | |
this.dead = deadCells; | |
this.alive = aliveCells; | |
this.squares = []; | |
} | |
Game.prototype = { | |
constructor: Game, | |
resetSquares: function () { | |
this.squares = []; | |
}, | |
fill: function () { | |
var x = 0; | |
var y = 0; | |
var proportions = canvas.width / size * canvas.height / size; | |
for (var i = 0; i < proportions; i++) { | |
if (x > canvas.width - size) { | |
x = 0; | |
y += size; | |
} | |
if (y > canvas.height - size) { | |
break; | |
} | |
var square = new Square(x, y, size, cx, color, 0); | |
square.draw(); | |
this.squares.push(square); | |
x += size; | |
} | |
console.log(this.squares); | |
}, | |
locateSquare: function (x, y) { | |
for (var i = 0; i < this.squares.length; i++) { | |
if (x >= this.squares[i].x && x <= (this.squares[i].x + this.squares[i].size - 1) && y >= this.squares[i].y && y <= (this.squares[i].y + this.squares[i].size - 1)) { | |
var searched = this.squares[i]; | |
return searched; | |
} | |
} | |
return false; | |
}, | |
getNeighbors: function (square) { | |
neighbors = []; | |
var x = square.x; | |
var y = square.y; | |
var step = square.size; | |
for (var i = 0; i < 8; i++) { | |
if (i == 0) { | |
x -= 1; | |
y -= 1; | |
} | |
var neighbor = this.locateSquare(x, y); | |
if (neighbor) { | |
neighbors.push(neighbor); | |
} | |
y += step; | |
if (i == 2) { | |
x += square.size + 2; | |
y = square.y - 1; | |
} | |
if (i == 5) { | |
x = square.x; | |
y = square.y - 1; | |
step = square.size + 2; | |
} | |
} | |
return neighbors; | |
}, | |
updateGrid: function () { | |
//var grid = this.squares; | |
for (var i = 0; i < this.squares.length; i++) { | |
var alive = 0; | |
var neighbors = this.getNeighbors(this.squares[i]) | |
//search for alive cells in neighbourhood | |
for (var x = 0; x < neighbors.length; x++) { | |
if (neighbors[x].state == 1) { | |
alive += 1; | |
} | |
} | |
//underpopulation | |
if (alive < 2 && this.squares[i].state == 1) { | |
this.squares[i].switchState(); | |
} | |
//overpopulation | |
else if (alive > 3 && this.squares[i].state == 1) { | |
this.squares[i].switchState(); | |
} | |
// three neighbors alive, dead cell wakes to life | |
else if (alive == 3 && this.squares[i].state === 0) { | |
this.squares[i].switchState(); | |
} | |
// mark cell which is alive and kickin' | |
if (this.squares[i].state === 1) { | |
this.squares[i].markRed(); | |
} else { | |
this.squares[i].draw(); | |
} | |
} | |
}, | |
getEvents: function () { | |
canvas.addEventListener('click', markSquare, false); | |
var grid = this; | |
function markSquare(ev) { | |
var clicked = grid.locateSquare(ev.offsetX, ev.offsetY); | |
clicked.switchState(); | |
} | |
} | |
} | |
var game = new Game(10, 100); | |
game.fill(); | |
game.getEvents(); | |
button.addEventListener('click', startConway, false); | |
sizer.addEventListener("change",login,false); | |
kill.addEventListener("click",killGame,false); | |
clear.addEventListener("click",clearGame,false); | |
function clearGame () { | |
cx.clearRect(0,0, canvas.width,canvas.height); | |
game.resetSquares(); | |
game.fill(); | |
} | |
function killGame () { | |
clearInterval(interval); | |
} | |
function login(e) { | |
size = Number(sizer.value); | |
cx.clearRect(0,0, canvas.width,canvas.height); | |
game.resetSquares(); | |
game.fill(); | |
} | |
function startConway() { | |
interval = setInterval(update, 1000); | |
function update() { | |
game.updateGrid(); | |
} | |
} |
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
body { | |
font-family:"georgia"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment