初始化项目并上传代码

This commit is contained in:
2026-04-08 20:56:47 +08:00
commit 2bd6c441d4
7 changed files with 1940 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
# Conway Life Demo Implementation Plan
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build a direct-open Conway's Game of Life demo page with a modern visualization style, preset patterns, canvas-based simulation, and a clean teaching-plus-exploration flow.
**Architecture:** Keep the page build-free and local-file friendly: semantic markup in `index.html`, visual styling in `styles.css`, and a single browser script in `app.js`. Put Conway engine logic and state helpers in testable pure functions exported from `app.js`, while the DOM/controller layer wires those functions to the canvas UI.
**Tech Stack:** HTML5, CSS3, vanilla JavaScript, Canvas API, Node.js built-in test runner (`node --test`)
---
Note: this workspace is not a git repository, so commit steps are intentionally omitted.
## File Structure
- Create: `index.html` - page structure, content sections, script/style includes
- Create: `styles.css` - theme variables, layout, cards, control panel, responsive styling, animation polish
- Create: `app.js` - Conway engine, preset definitions, state helpers, canvas rendering, UI events
- Create: `tests/life-demo.test.js` - Node tests for pure simulation and state logic
## Chunk 1: Build and test the Conway engine
### Task 1: Create the failing engine tests
**Files:**
- Create: `tests/life-demo.test.js`
- Test: `tests/life-demo.test.js`
- [ ] **Step 1: Write the failing test**
```js
const test = require('node:test');
const assert = require('node:assert/strict');
const {
createEmptyGrid,
stepGrid,
stampPattern,
PATTERNS,
} = require('../app.js');
test('blinker rotates after one generation', () => {
const grid = createEmptyGrid(5, 5);
grid[2][1] = 1;
grid[2][2] = 1;
grid[2][3] = 1;
const next = stepGrid(grid);
assert.deepEqual(next[1], [0, 0, 1, 0, 0]);
});
```
- [ ] **Step 2: Run test to verify it fails**
Run: `node --test tests/life-demo.test.js`
Expected: FAIL because `app.js` or the exported functions do not exist yet.
- [ ] **Step 3: Write minimal implementation**
```js
function createEmptyGrid(rows, cols) {
return Array.from({ length: rows }, () => Array(cols).fill(0));
}
```
Implement the smallest export set needed to pass:
- `createEmptyGrid(rows, cols)`
- `countLiveNeighbors(grid, row, col)`
- `stepGrid(grid)`
- `stampPattern(grid, pattern, offsetRow, offsetCol)`
- `PATTERNS` for `glider`, `pulsar`, and `gosperGliderGun`
- [ ] **Step 4: Run test to verify it passes**
Run: `node --test tests/life-demo.test.js`
Expected: PASS for the engine tests.
## Chunk 2: Add state helpers and page shell
### Task 2: Add failing tests for state helpers
**Files:**
- Modify: `tests/life-demo.test.js`
- Modify: `app.js`
- Create: `index.html`
- Create: `styles.css`
- [ ] **Step 1: Write the failing test**
Add tests for:
```js
test('createInitialState seeds the default preset and starts paused', () => {
const state = createInitialState({
rows: 20,
cols: 20,
defaultPattern: 'pulsar',
});
assert.equal(state.running, false);
assert.equal(state.selectedPattern, 'pulsar');
assert.equal(state.generation, 0);
assert.ok(state.liveCount > 0);
});
```
- [ ] **Step 2: Run test to verify it fails**
Run: `node --test tests/life-demo.test.js`
Expected: FAIL because `createInitialState` is not implemented yet.
- [ ] **Step 3: Write minimal implementation**
Implement pure helpers:
- `cloneGrid(grid)`
- `countLiveCells(grid)`
- `createInitialState({ rows, cols, defaultPattern })`
- `randomizeGrid(grid, probability)`
- `toggleCell(grid, row, col, forcedValue)`
At the same time, scaffold:
- `index.html` with Hero, Lab, Rules, and Presets sections
- `styles.css` with the modern visualization theme variables and responsive grid
- [ ] **Step 4: Run test to verify it passes**
Run: `node --test tests/life-demo.test.js`
Expected: PASS for the new state-helper tests.
## Chunk 3: Wire controls, canvas rendering, and preset switching
### Task 3: Add failing tests for UI-facing state transitions
**Files:**
- Modify: `tests/life-demo.test.js`
- Modify: `app.js`
- Modify: `index.html`
- Modify: `styles.css`
- [ ] **Step 1: Write the failing test**
Add tests for:
```js
test('applyPreset replaces the grid, pauses playback, and resets generation', () => {
const state = {
...createInitialState({ rows: 25, cols: 25, defaultPattern: 'glider' }),
running: true,
generation: 12,
};
const next = applyPreset(state, 'gosperGliderGun');
assert.equal(next.running, false);
assert.equal(next.generation, 0);
assert.equal(next.selectedPattern, 'gosperGliderGun');
assert.ok(next.liveCount > state.liveCount);
});
```
- [ ] **Step 2: Run test to verify it fails**
Run: `node --test tests/life-demo.test.js`
Expected: FAIL because `applyPreset` is not implemented yet.
- [ ] **Step 3: Write minimal implementation**
Implement:
- `applyPreset(state, patternName)`
- `advanceState(state)`
- `setSpeed(state, speed)`
- `getSpeedLabel(speed)`
Then wire browser behavior:
- draw the grid on a `canvas`
- support play/pause, step, clear, randomize, reset preset, and speed controls
- support click and drag painting on the canvas
- update status text, generation count, live-count, and active preset styling
- [ ] **Step 4: Run test to verify it passes**
Run: `node --test tests/life-demo.test.js`
Expected: PASS for the state-transition tests.
## Chunk 4: Polish visual details and run end-to-end verification
### Task 4: Finish presentation details and verify manually
**Files:**
- Modify: `index.html`
- Modify: `styles.css`
- Modify: `app.js`
- Test: `tests/life-demo.test.js`
- [ ] **Step 1: Refine the visuals**
Complete:
- luminous background gradients and grid accents
- polished cards and control panel surfaces
- hover/focus states
- responsive stacking for smaller screens
- subtle canvas/section entrance motion
- [ ] **Step 2: Run automated tests**
Run: `node --test tests/life-demo.test.js`
Expected: PASS with zero failures.
- [ ] **Step 3: Run manual verification**
Open: `index.html`
Verify:
- page opens directly without a dev server
- pulsar loads by default and the simulation starts paused
- controls behave correctly
- each preset loads and pauses correctly
- editing by click/drag works
- desktop and narrow layouts both remain usable
- [ ] **Step 4: Record any gaps**
If a browser-only issue appears, fix it and rerun:
- `node --test tests/life-demo.test.js`
- manual browser verification of `index.html`

View File

@@ -0,0 +1,105 @@
# Conway Life Demo Design
Date: 2026-03-17
Status: Approved
## Goal
Build a pure HTML/CSS/JS demo page for Conway's Game of Life that opens directly from `index.html`, balances teaching and interaction, and presents the simulation with a modern visualization aesthetic.
## Audience and Use Case
- Learners seeing cellular automata for the first time
- Users who want to experiment by drawing patterns and watching them evolve
- Anyone who wants a polished, shareable standalone demo page
## Product Direction
- Topic: Conway's Game of Life
- Page type: balanced demo page
- Delivery: direct-open HTML/CSS/JS page
- Feature scope: enhanced version with preset patterns
- Visual style: modern visualization
- Default state: load a preset pattern and remain paused
## Layout
### 1. Hero
- Full-width first screen with an atmospheric simulation-inspired background
- Title, short explanatory subtitle, and a clear entry action that scrolls to the lab
- Visual treatment based on luminous grid lines, soft glow, and scientific/data-art styling
### 2. Main Lab
- Large simulation canvas as the primary focus
- Side control panel on desktop; stacked layout on mobile
- Status area showing running/paused state and current speed
### 3. Rules Section
- Three compact rule cards explaining survival, birth, and death
- Short copy only; no heavy educational text blocks
- Small visual motifs to keep the explanation approachable
### 4. Preset Pattern Section
- Presets: glider, pulsar, and Gosper glider gun
- Clicking a preset loads it into the simulation and pauses playback
- Section doubles as both a teaching aid and a quick demo launcher
## Interaction Design
### Controls
- Start/Pause
- Step one generation
- Clear
- Randomize
- Reset to selected preset
- Speed adjustment
### Canvas Interaction
- Click a cell to toggle it
- Drag to paint cells continuously
- Keep the simulation paused when loading or editing presets so the user stays in control
### Simulation Rules
- Classic Conway rules
- Finite grid with non-wrapping edges
- Default opening preset: pulsar
## Visual System
- Deep dark background with cool white text
- Cyan and acid-green highlights for live-state emphasis
- Semi-transparent panels, subtle borders, soft bloom, and layered gradients
- Refined motion: gentle glow, state transitions, and staggered reveal rather than flashy arcade effects
## Technical Approach
- Use `canvas` for the simulation surface to keep updates smooth and visually polished
- Keep simulation rules in pure functions so they can be tested outside the browser
- Keep page assets local so `index.html` can open directly without a build step
## Responsiveness
- Desktop: wide lab layout with canvas first and controls beside it
- Mobile: stacked layout with the canvas above controls
- Preset cards become horizontally scrollable on narrower screens
## Usability Details
- Disable actions when they should not apply, such as disabling step while running
- Show the active preset and speed tier clearly
- Short helper copy explaining that each cell looks at its eight neighbors
## Verification Targets
- Conway rule updates are correct
- Start/pause and single-step work as expected
- Presets load correctly
- Editing cells updates the simulation state correctly
- Layout remains usable after resizing