From c189268b434fb119a7c348a80968c6651728b792 Mon Sep 17 00:00:00 2001 From: pearmini Date: Fri, 22 Aug 2025 20:59:51 -0400 Subject: [PATCH] Add matrix rain --- examples/index.js | 20 +++++++------ examples/matrix-rain.js | 66 +++++++++++++++++++++++++++++++++++++++++ src/App.jsx | 2 +- 3 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 examples/matrix-rain.js diff --git a/examples/index.js b/examples/index.js index 0f8fe7f..5872ee6 100644 --- a/examples/index.js +++ b/examples/index.js @@ -1,12 +1,13 @@ -import { helloWorld } from './hello-world.js'; -import { addition } from './addition.js'; -import { inspector } from './inspector.js'; -import { promise } from './promise.js'; -import { generator } from './generator.js'; -import { syntaxError } from './syntax-error.js'; -import { runtimeError } from './runtime-error.js'; -import { randomHistogram } from './random-histogram.js'; -import { mandelbrotSet } from './mandelbrot-set.js'; +import {helloWorld} from "./hello-world.js"; +import {addition} from "./addition.js"; +import {inspector} from "./inspector.js"; +import {promise} from "./promise.js"; +import {generator} from "./generator.js"; +import {syntaxError} from "./syntax-error.js"; +import {runtimeError} from "./runtime-error.js"; +import {randomHistogram} from "./random-histogram.js"; +import {mandelbrotSet} from "./mandelbrot-set.js"; +import {matrixRain} from "./matrix-rain.js"; export const examples = [ helloWorld, @@ -18,4 +19,5 @@ export const examples = [ runtimeError, randomHistogram, mandelbrotSet, + matrixRain, ]; diff --git a/examples/matrix-rain.js b/examples/matrix-rain.js new file mode 100644 index 0000000..b8889a6 --- /dev/null +++ b/examples/matrix-rain.js @@ -0,0 +1,66 @@ +const code = `const width = 60; +const height = 25; +const columns = d3.range(width).map(() => createColumn(height)); + +{ + frame; + + // Create a new buffer. + const buffer = d3.range(width * height).map(() => " "); + + // Update all columns. + for (let i = columns.length - 1; i >= 0; --i) { + const column = columns[i]; + const {lifespan, length, chars} = column; + const n = chars.length; + if (lifespan < 0) columns[i] = createColumn(height); + else if (lifespan <= n) chars[n - lifespan] = " "; + else { + for (let j = length - 1; j < n; ++j) chars[j] = randomChar(); + chars.push(randomChar()); + } + column.lifespan -= 1; + } + + // Update the buffer. + for (let i = 0; i < columns.length; ++i) { + const column = columns[i]; + const {y, chars} = column; + for (let j = 0; j < chars.length; ++j) buffer[(y + j) * width + i] = chars[j]; + } + + // Render the buffer. + let output = ""; + for (let i = 0; i < height; ++i) { + for (let j = 0; j < width; ++j) output += buffer[i * width + j]; + output += i === height - 1 ? "" : "\\n"; + } + output = output.split("\\n").map(d => " " + d).join("\\n"); + doc(output); +} + +function createColumn(height) { + const lifespan = d3.randomInt(height)(); + const length = d3.randomInt(lifespan)(); + const chars = d3.range(length).map(randomChar); + const y = d3.randomInt(0, 10)(); + return {lifespan, length, chars, y}; +} + +function randomChar() { + return String.fromCharCode(d3.randomInt(32, 127)()); +} + +const frame = (async function* () { + for (let i = 0; true; ++i) { + yield i; + await new Promise((resolve) => setTimeout(resolve, 1000 / 15)); + } +})(); + +const d3 = require("d3");`; + +export const matrixRain = { + name: "Matrix Rain", + code, +}; diff --git a/src/App.jsx b/src/App.jsx index 3b32e74..f84db0f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -42,7 +42,7 @@ export default function App() {

Observable Script