Skip to content

Instantly share code, notes, and snippets.

@qubyte
Created November 13, 2019 12:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qubyte/6ade7b39ba5491272134785804642ee5 to your computer and use it in GitHub Desktop.
Save qubyte/6ade7b39ba5491272134785804642ee5 to your computer and use it in GitHub Desktop.
Conway's Game of Life. I put this together quickly as something to iterate on as a generative art project.
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="index.js"></script>
<title>Game of Life</title>
<meta charset="utf-8">
</head>
<body>
<h1>Game of Life</h1>
<canvas width="600" height="600"></canvas>
</body>
</html>
const [canvas] = document.getElementsByTagName('canvas');
if (!canvas) {
throw new Error('No canvas!');
}
const context = canvas.getContext('2d');
const nDivisions = 50;
const cellLiveProb = 0.5;
const { width, height } = canvas;
const cellWidth = width / nDivisions;
const cellHeight = height / nDivisions;
function randomGrid() {
return Uint8Array.from({ length: nDivisions ** 2 }, () => Math.random() < cellLiveProb ? 1 : 0);
}
function calculateNext(grid) {
const next = new Uint8Array(nDivisions ** 2); // Initialized to 0;
for (let i = 0; i < nDivisions; i++) {
for (let j = 0; j < nDivisions; j++) {
let count = 0;
// Iterate over neighbouring indices.
for (let x = i - 1; x <= i + 1; x++) {
for (let y = j - 1; y <= j + 1; y++) {
// Ignore self.
if (x !== i || y !== j) {
// If indices off end of grid, loop around.
const loopedX = x < 0 ? nDivisions + x : x > (nDivisions - 1) ? x - nDivisions : x;
const loopedY = y < 0 ? nDivisions + y : y > (nDivisions - 1) ? y - nDivisions : y;
// Add neighbour to count.
count += grid[loopedX * nDivisions + loopedY];
}
}
}
const gridIndex = i * nDivisions + j;
if (count === 3 || (count === 2 && grid[gridIndex])) {
next[gridIndex] = 1;
}
}
}
return next;
}
function draw(grid) {
context.clearRect(0, 0, width, height);
for (let i = 0; i < nDivisions; i++) {
for (let j = 0; j < nDivisions; j++) {
if (grid[i * nDivisions + j]) {
context.fillRect(cellWidth * i, cellHeight * j, cellWidth, cellHeight);
}
}
}
setTimeout(draw, 50, calculateNext(grid));
}
draw(randomGrid());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment