JSFiddle - React, Tailwind, and code Playground
HTML
<h1>Conway's Game of Life</h1>
<div id="view">
<label>speed 0
<input id="speed" type="range" min="0" max="180" /> 180</label>
<table id="conway"></table>
</div>
CSS
.conway {
width: auto;
border-collapse: collapse;
}
.conway .cell {
width: 10px;
height: 10px;
border: 1px solid #eee;
}
.conway .live {
background: red;
}
JavaScript
/**
* Conway in plain JS
* (c) 2014 Ben Lesh
* MIT License
*/
// Clear the console, just because I hate it getting
// junked up while I'm playing in JSFiddle
console.clear();
(function(window, document) {
// The Controller for our game;
function Grid(w, h) {
var grid = this;
grid.width = w;
grid.height = h;
// this is the Model, really
grid.rows = null;
// use this to initialize or reset the grid
grid.reset = function() {
var x, y, row;
grid.rows = [];
for (y = 0; y < h; y++) {
row = [];
for (x = 0; x < w; x++) {
row.push(new Cell(x, y));
}
grid.rows.push(row);
}
}
// call it right away to initialize the grid
grid.reset();
// utility to run through all of the cells
// in the grid's rows.
grid.traverse = function(fn) {
var x, y;
var context = {
stop: false
};
outer: for (y = 0; y < grid.height; y++) {
for (x = 0; x < grid.width; x++) {
fn(context, grid.rows[y][x], x, y);
if (context.stop) {
break outer;
}
}
}
}
grid.step = function() {
// first go trough and count live neighbors
// *before* you update each cell.
// Otherwise you'll ruin the live neighbor count
// for the next one.
grid.traverse(function(ctxt, cell) {
cell.examine();
});
// *Now* let's update the cells life status.
grid.traverse(function(ctxt, cell) {
cell.update();
});
};
// The model for an individual cell
function Cell(x, y) {
var cell = this;
cell.x = x;
cell.y = y;
cell.live = false;
cell.grid = grid;
}
// counts nearby living neighbors
// and updates cell.liveNeighbors
Cell.prototype.examine = function() {
var cell = this;
cell.liveNeighbors = 0;
cell.traverseNearby(function(ctxt, neighbor) {
if...