From 4026c8093e6364d59016d912c53c274ac4b5ef04 Mon Sep 17 00:00:00 2001 From: log101 Date: Wed, 1 May 2024 09:12:27 +0300 Subject: [PATCH] add gol script --- package-lock.json | 6 ++++ package.json | 1 + src/pages/index.astro | 4 +++ src/scripts/gol.js | 74 +++++++++++++++++++++++++++++++++++++++++++ src/styles/gol.css | 13 ++++++++ 5 files changed, 98 insertions(+) create mode 100644 src/scripts/gol.js create mode 100644 src/styles/gol.css 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'; --- +<div id="board" class="board"></div> +<button id="startButton">Start Game</button> +<script src="../scripts/gol.js"></script> 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; +}