Skip to content

Instantly share code, notes, and snippets.

@BenJanecke
Created October 6, 2022 21:43
Show Gist options
  • Save BenJanecke/8ce65999441b98c9978c7a63f8c5682c to your computer and use it in GitHub Desktop.
Save BenJanecke/8ce65999441b98c9978c7a63f8c5682c to your computer and use it in GitHub Desktop.
Game of life comparison
function main(width = 50, height = 20, refreshRate = 250) {
let life = generateRandomBoard(width, height);
draw(life);
setInterval(() => {
life = nextGeneration(life);
draw(life);
}, refreshRate);
}
const states = {
live: "x",
dead: "-",
};
const nextGeneration = (board) =>
board.map((row, ri) => {
const prevRow = board[ri - 1] || [];
const nextRow = board[ri + 1] || [];
return row.map((cell, ci) => {
const neighbours = [
prevRow[ci - 1],
prevRow[ci],
prevRow[ci + 1],
row[ci - 1],
row[ci + 1],
nextRow[ci - 1],
nextRow[ci],
nextRow[ci + 1],
];
const live = neighbours
.join("")
.replace(new RegExp(states.dead, "g"), "").length;
// Any live cell with two or three live neighbours survives.
if (cell === states.live && (live === 2 || live === 3)) {
return states.live;
}
// Any dead cell with three live neighbours becomes a live cell.
if (cell === states.dead && live === 3) {
return states.live;
}
// All other live cells die in the next generation. Similarly, all other dead cells stay dead.
return states.dead;
});
});
function draw(board) {
const border = `${(board[0] ?? []).map((_) => "-").join("")}`;
console.clear();
console.log(
`/${border}\\\n${board
.map((row) => `|${row.join("")}|`)
.join("\n")}\n\\${border}/`
);
}
const generateRandomBoard = (width = 0, height = 0) =>
Array.from({ length: height }, (_, y) => {
return Array.from({ length: width }, (_, x) => {
return randomCell();
});
});
const randomCell = () => (Math.random() * 10 > 6 ? states.live : states.dead);
main();
function main(widht, height, refreshRate) {
var w = widht || 50,
h = height || 20,
rr = refreshRate || 250;
var life = randomLife(w, h);
draw(life);
setInterval(() => {
life = generation(life);
draw(life);
}, rr);
}
var live = "x";
var dead = "-";
function generation(life) {
var next = [];
for (var r = 0; r < life.length; r++) {
var row = life[r];
next.push([]);
for (var c = 0; c < row.length; c++) {
var cell = row[c];
var liveNeighbors = countLiveNeighbors(c, r, life);
if (cell === live && (liveNeighbors === 2 || liveNeighbors === 3)) {
// Any live cell with two or three live neighbours survives.
next[r][c] = live;
} else if (cell === dead && liveNeighbors === 3) {
// Any dead cell with three live neighbours becomes a live cell.
next[r][c] = live;
} else {
// All other live cells die in the next generation. Similarly, all other dead cells stay dead.
next[r][c] = dead;
}
}
}
return next;
}
function draw(life) {
var output = "/";
for (var c = 0; c < life[0].length; c++) {
output += "-";
}
output += "\\\n";
for (var r = 0; r < life.length; r++) {
var row = life[r];
for (var c = 0; c < row.length; c++) {
if (c === 0) {
output += "|";
}
var cell = row[c];
output += cell;
if (c === row.length - 1) {
output += "|";
}
}
output += "\n";
}
output += "\\";
for (var c = 0; c < life[0].length; c++) {
output += "-";
}
output += "/";
console.clear();
console.log(output);
}
function countLiveNeighbors(c, r, life) {
return (
getCell(c - 1, r - 1, life) +
getCell(c, r - 1, life) +
getCell(c + 1, r - 1, life) +
getCell(c - 1, r, life) +
getCell(c, r, life) +
getCell(c - 1, r + 1, life) +
getCell(c, r + 1, life) +
getCell(c + 1, r + 1, life)
).replace(new RegExp(dead, "g"), "").length;
}
function getCell(c, r, life) {
return (life[r] || [])[c] || dead;
}
function randomCell() {
return Math.random() * 10 > 6 ? live : dead;
}
function randomLife(width = 0, height = 0) {
var out = [];
for (let r = 0; r < height; r++) {
out.push([]);
for (let c = 0; c < width; c++) {
out[r].push(randomCell());
}
}
return out;
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment