Published
Edited
Feb 15, 2020
25 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Run Stingrays ruleset, updating `cells` with new values (`lastCells` as scratchpad)
function computeNextCells() {
lastCells.set(cells);
let index = 0; // Cell buffer index
let neighborCount = 0; // Neighbor cell count

for (let y = 0; y < gridHeight; y++) {
let up = y - 1;
let down = y + 1;

// Clamp to cell boundaries
if (up < 0) up = gridHeight - 1;
else if (down >= gridHeight) down = 0;

// Pre-multiply y values
up *= gridWidth;
down *= gridWidth;
const center = y * gridWidth;

for (let x = 0; x < gridWidth; x++) {
let left = x - 1;
let right = x + 1;

// Clamp to cell boundaries
if (left < 0) left = gridWidth - 1;
else if (right >= gridWidth) right = 0;

// Count neighboring cell values (not including center cell)
neighborCount =
lastCells[up + left] +
lastCells[up + x] +
lastCells[up + right] +
lastCells[center + left] +
lastCells[center + right] +
lastCells[down + left] +
lastCells[down + x] +
lastCells[down + right];

// If neighbor count is in mid-range, clear center cell (regardless of its current value)
if (neighborCount >= 6 && neighborCount <= 9) {
cells[index] = 0;
}
// If neighbor count too high, give it a value (regardless of its current value)
else if (neighborCount >= 10) {
cells[index] = 1;
}
// If center cell is occupied...
else if (lastCells[index] > 0) {
// Clear it if neighbor count too high or low
if (neighborCount <= 3 || neighborCount >= 7) cells[index] = 0;
}
// If center cell is not occupied...
else {
// Give it a value if neighbor count is at certain threshold values
if (neighborCount == 5) cells[index] = 1;
else if (neighborCount == 3) cells[index] = 2;
}

index++;
}
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more