Conways Game of life is now a background ...
This commit is contained in:
@@ -0,0 +1,105 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
|
<canvas id="gol-canvas" class="fixed top-0 left-0 w-full h-full -z-10 opacity-20"></canvas>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const canvas = document.getElementById('gol-canvas') as HTMLCanvasElement;
|
||||||
|
const ctx = canvas.getContext('2d')!;
|
||||||
|
const size = 12;
|
||||||
|
|
||||||
|
let cols: number;
|
||||||
|
let rows: number;
|
||||||
|
let grid: boolean[][];
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
cols = Math.floor(canvas.width / size);
|
||||||
|
rows = Math.floor(canvas.height / size);
|
||||||
|
grid = createGrid();
|
||||||
|
seed();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGrid() {
|
||||||
|
return Array.from({ length: rows }, () => Array(cols).fill(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(g: boolean[][], r: number, c: number) {
|
||||||
|
if (r >= 0 && r < rows && c >= 0 && c < cols) g[r][c] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function seed() {
|
||||||
|
// Gosper Glider Gun - top left
|
||||||
|
const gun = [
|
||||||
|
[0,24],[1,22],[1,24],[2,12],[2,13],[2,20],[2,21],[2,34],[2,35],
|
||||||
|
[3,11],[3,15],[3,20],[3,21],[3,34],[3,35],[4,0],[4,1],[4,10],
|
||||||
|
[4,16],[4,20],[4,21],[5,0],[5,1],[5,10],[5,14],[5,16],[5,17],
|
||||||
|
[5,22],[5,24],[6,10],[6,16],[6,24],[7,11],[7,15],[8,12],[8,13],
|
||||||
|
];
|
||||||
|
gun.forEach(([r, c]) => set(grid, 2 + r, 2 + c));
|
||||||
|
|
||||||
|
// R-pentomino - center (chaotic long-lived)
|
||||||
|
const or = Math.floor(rows / 2);
|
||||||
|
const oc = Math.floor(cols / 2);
|
||||||
|
[[0,1],[0,2],[1,0],[1,1],[2,1]].forEach(([r,c]) => set(grid, or+r, oc+c));
|
||||||
|
|
||||||
|
// Acorn - right side (takes 5206 generations)
|
||||||
|
const ar = Math.floor(rows / 3);
|
||||||
|
const ac = Math.floor(cols * 0.7);
|
||||||
|
[[0,1],[1,3],[2,0],[2,1],[2,4],[2,5],[2,6]].forEach(([r,c]) => set(grid, ar+r, ac+c));
|
||||||
|
|
||||||
|
// Pulsar - bottom left (period 3 oscillator)
|
||||||
|
const pr = Math.floor(rows * 0.7);
|
||||||
|
const pc = Math.floor(cols * 0.2);
|
||||||
|
[
|
||||||
|
[0,2],[0,3],[0,4],[0,8],[0,9],[0,10],
|
||||||
|
[2,0],[2,5],[2,7],[2,12],
|
||||||
|
[3,0],[3,5],[3,7],[3,12],
|
||||||
|
[4,0],[4,5],[4,7],[4,12],
|
||||||
|
[4,2],[4,3],[4,4],[4,8],[4,9],[4,10],
|
||||||
|
[6,2],[6,3],[6,4],[6,8],[6,9],[6,10],
|
||||||
|
[7,0],[7,5],[7,7],[7,12],
|
||||||
|
[8,0],[8,5],[8,7],[8,12],
|
||||||
|
[9,0],[9,5],[9,7],[9,12],
|
||||||
|
[10,2],[10,3],[10,4],[10,8],[10,9],[10,10],
|
||||||
|
].forEach(([r,c]) => set(grid, pr+r, pc+c));
|
||||||
|
|
||||||
|
// Lightweight spaceship - bottom right
|
||||||
|
const sr = Math.floor(rows * 0.75);
|
||||||
|
const sc = Math.floor(cols * 0.65);
|
||||||
|
[[0,1],[0,4],[1,0],[2,0],[2,4],[3,0],[3,1],[3,2],[3,3]].forEach(([r,c]) => set(grid, sr+r, sc+c));
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
const g = createGrid();
|
||||||
|
for (let r = 0; r < rows; r++) {
|
||||||
|
for (let c = 0; c < cols; c++) {
|
||||||
|
let n = 0;
|
||||||
|
for (let dr = -1; dr <= 1; dr++)
|
||||||
|
for (let dc = -1; dc <= 1; dc++)
|
||||||
|
if ((dr || dc) && grid[(r+dr+rows)%rows]?.[(c+dc+cols)%cols]) n++;
|
||||||
|
if (grid[r][c]) g[r][c] = n === 2 || n === 3;
|
||||||
|
else g[r][c] = n === 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid = g;
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
const color = getComputedStyle(document.documentElement).getPropertyValue('--ctp-accent').trim();
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
for (let r = 0; r < rows; r++)
|
||||||
|
for (let c = 0; c < cols; c++)
|
||||||
|
if (grid[r][c]) ctx.fillRect(c * size, r * size, size - 1, size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tick() {
|
||||||
|
next();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
resize();
|
||||||
|
setInterval(tick, 100);
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Blank from '../layouts/Blank.astro';
|
import Blank from '../layouts/Blank.astro';
|
||||||
|
import GameOfLife from '../components/GameOfLife.astro';
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
{ label: "Blog", href: "/blog", icon: "/blog.png"},
|
{ label: "Blog", href: "/blog", icon: "/blog.png"},
|
||||||
@@ -13,6 +14,7 @@ const links = [
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Blank title="cyperpunk.de">
|
<Blank title="cyperpunk.de">
|
||||||
|
<GameOfLife />
|
||||||
<div class="flex flex-col items-center gap-8">
|
<div class="flex flex-col items-center gap-8">
|
||||||
<div class="flex flex-col items-center gap-2">
|
<div class="flex flex-col items-center gap-2">
|
||||||
<img src="/avatar.jpg" alt="DerGrumpf" class="w-42 h-42 rounded-full object-cover" />
|
<img src="/avatar.jpg" alt="DerGrumpf" class="w-42 h-42 rounded-full object-cover" />
|
||||||
|
|||||||
Reference in New Issue
Block a user