Task 1 of 5
A cellular automaton is a world of cells, each one dead (0) or alive
(1), where every cell's next state depends only on its immediate neighborhood.
That makes it embarrassingly parallel: 256 cells, 256 threads, and no thread needs to know
what any other thread is doing — only what the grid looked like.
Every rule in this module starts with the same question: how many of my eight
neighbors are alive? This world is a torus — walk off the right edge, reappear on
the left — and wrapping costs one modulo: (x + dx + 16) % 16. The
+ 16 is not decoration: JavaScript's % can go negative while the
GPU's cannot, and adding the width first keeps both operands positive so CPU mode and GPU
mode tell the same story.
dy/dx loops from −1 to 1(this.thread.x + dx + 16) % 16 (and the same for y)Two statically bounded loops: for (let dy = -1; dy < 2; dy++)
around for (let dx = -1; dx < 2; dx++). Nine visits per cell.
Skipping the middle of the 3×3 block needs no if: sum all nine
cells, then subtract grid[this.thread.y][this.thread.x] at the end. If
you're dead you subtract 0; if you're alive you take yourself back out.
const yy = (this.thread.y + dy + 16) % 16;
const xx = (this.thread.x + dx + 16) % 16;
count += grid[yy][xx];
— then
return count - grid[this.thread.y][this.thread.x];This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.