JSFiddle - React, Tailwind, and code Playground

by velo_ninja

HTML

<canvas id="gameCanvas" width="400" height="400"></canvas>

CSS

body {
  background: #111;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
canvas {
  border: 1px solid #444;
}

JavaScript

const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");

const cols = 40;
const rows = 40;
const resolution = canvas.width / cols;

let grid = createGrid();

function createGrid() {
  return new Array(rows).fill(null).map(() =>
    new Array(cols).fill(null).map(() => Math.floor(Math.random() * 2))
  );
}

function drawGrid(grid) {
  for (let y = 0; y < rows; y++) {
    for (let x = 0; x < cols; x++) {
      const cell = grid[y][x];
      ctx.beginPath();
      ctx.rect(x * resolution, y * resolution, resolution, resolution);
      ctx.fillStyle = cell ? "#00FF00" : "#111";
      ctx.fill();
      ctx.strokeStyle = "#222";
      ctx.stroke();
    }
  }
}

function nextGeneration(grid) {
  const next = createGrid();
  for (let y = 0; y < rows; y++) {
    for (let x = 0; x < cols; x++) {
      const cell = grid[y][x];
      const neighbors = countNeighbors(grid, x, y);

      if (cell === 1 && (neighbors < 2 || neighbors > 3)) {
        next[y][x] = 0;
      } else if (cell === 0 && neighbors === 3) {
        next[y][x] = 1;
      } else {
        next[y][x] = cell;
      }
    }
  }
  return next;
}

function countNeighbors(grid, x, y) {
  let sum = 0;
  for (let i = -1; i < 2; i++) {
    for (let j = -1; j < 2; j++) {
      if (i === 0 && j === 0) continue;
      const col = (x + j + cols) % cols;
      const row = (y + i + rows) % rows;
      sum += grid[row][col];
    }
  }
  return sum;
}

function update() {
  drawGrid(grid);
  grid = nextGeneration(grid);
  requestAnimationFrame(update);
}

update();