初始化项目并上传代码

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`