diff --git a/package-lock.json b/package-lock.json
index f717867..6bc3256 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@astrojs/check": "^0.5.10",
"@astrojs/lit": "^4.0.1",
"@webcomponents/template-shadowroot": "^0.2.1",
+ "animejs": "^3.2.2",
"astro": "^4.7.0",
"lit": "^3.1.3",
"typescript": "^5.4.5"
@@ -1862,6 +1863,11 @@
"node": ">=0.4.0"
}
},
+ "node_modules/animejs": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.2.tgz",
+ "integrity": "sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ=="
+ },
"node_modules/ansi-align": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
diff --git a/package.json b/package.json
index af3e4fc..3bdeebd 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@astrojs/check": "^0.5.10",
"@astrojs/lit": "^4.0.1",
"@webcomponents/template-shadowroot": "^0.2.1",
+ "animejs": "^3.2.2",
"astro": "^4.7.0",
"lit": "^3.1.3",
"typescript": "^5.4.5"
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 4d34a7d..b51d120 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,5 +1,9 @@
---
import { Title } from '../components/header';
+import '../styles/gol.css';
---
+
+
+
diff --git a/src/scripts/gol.js b/src/scripts/gol.js
new file mode 100644
index 0000000..890785e
--- /dev/null
+++ b/src/scripts/gol.js
@@ -0,0 +1,74 @@
+const boardElement = document.getElementById('board');
+const boardSize = 20;
+const grid = [];
+let intervalId;
+
+function initializeBoard() {
+ for (let y = 0; y < boardSize; y++) {
+ let row = [];
+ for (let x = 0; x < boardSize; x++) {
+ let cell = document.createElement('div');
+ cell.classList.add('cell');
+ cell.addEventListener('click', () => {
+ cell.classList.toggle('alive');
+ grid[y][x] = grid[y][x] ? 0 : 1;
+ });
+ boardElement.appendChild(cell);
+ row.push(0);
+ }
+ grid.push(row);
+ }
+}
+
+function computeNextGeneration() {
+ let changes = [];
+
+ grid.forEach((row, y) => {
+ row.forEach((cell, x) => {
+ let aliveNeighbors = countAliveNeighbors(y, x);
+ if (cell === 1 && (aliveNeighbors < 2 || aliveNeighbors > 3)) {
+ changes.push({ y, x, state: 0 });
+ } else if (cell === 0 && aliveNeighbors === 3) {
+ changes.push({ y, x, state: 1 });
+ }
+ });
+ });
+
+ changes.forEach(change => {
+ grid[change.y][change.x] = change.state;
+ const cellElement = boardElement.children[change.y * boardSize + change.x];
+ cellElement.animate([
+ { backgroundColor: change.state ? 'black' : 'white' }
+ ], {
+ duration: 300,
+ fill: 'forwards'
+ });
+ });
+}
+
+function countAliveNeighbors(y, x) {
+ let count = 0;
+ for (let yOffset = -1; yOffset <= 1; yOffset++) {
+ for (let xOffset = -1; xOffset <= 1; xOffset++) {
+ if (yOffset === 0 && xOffset === 0) continue;
+ let newY = y + yOffset;
+ let newX = x + xOffset;
+ if (newY >= 0 && newY < boardSize && newX >= 0 && newX < boardSize) {
+ count += grid[newY][newX];
+ }
+ }
+ }
+ return count;
+}
+
+function startGame() {
+ console.log('starting')
+ if (intervalId) clearInterval(intervalId);
+ intervalId = setInterval(computeNextGeneration, 100);
+}
+
+const startButton = document.getElementById('startButton')
+
+startButton.onclick = startGame
+
+initializeBoard();
diff --git a/src/styles/gol.css b/src/styles/gol.css
new file mode 100644
index 0000000..3bd1b2f
--- /dev/null
+++ b/src/styles/gol.css
@@ -0,0 +1,13 @@
+.board {
+ display: grid;
+ grid-template-columns: repeat(20, 20px);
+ grid-gap: 1px;
+}
+.cell {
+ width: 20px;
+ height: 20px;
+ background-color: white;
+}
+.alive {
+ background-color: black;
+}