import React, { useState, useCallback, useRef, useEffect } from 'react'; import { Play, Pause, FastForward, RotateCcw, Shuffle, Trash2, Info } from 'lucide-react'; // 初始网格大小 const numRows = 30; const numCols = 30; // 邻居的坐标偏移量 (上、下、左、右、左上、右上、左下、右下) const operations = [ [0, 1], [0, -1], [1, -1], [-1, 1], [1, 1], [-1, -1], [1, 0], [-1, 0] ]; const generateEmptyGrid = () => { const rows = []; for (let i = 0; i < numRows; i++) { rows.push(Array.from(Array(numCols), () => 0)); } return rows; }; const App = () => { const [grid, setGrid] = useState(() => generateEmptyGrid()); const [running, setRunning] = useState(false); const [generation, setGeneration] = useState(0); const [speed, setSpeed] = useState(100); // 毫秒 const runningRef = useRef(running); runningRef.current = running; // 核心逻辑:计算下一代 const runSimulation = useCallback(() => { if (!runningRef.current) { return; } setGrid((g) => { // 深拷贝当前网格 (类似于我们之前的 Python 练习,不能直接修改原图) const gridCopy = JSON.parse(JSON.stringify(g)); for (let i = 0; i < numRows; i++) { for (let j = 0; j < numCols; j++) { let neighbors = 0; // 检查8个邻居 operations.forEach(([x, y]) => { const newI = i + x; const newJ = j + y; // 边界检查:确保没有越界 (类似于 x >= 0 and x < n) if (newI >= 0 && newI < numRows && newJ >= 0 && newJ < numCols) { neighbors += g[newI][newJ]; } }); // 康威生命游戏规则 if (neighbors < 2 || neighbors > 3) { gridCopy[i][j] = 0; // 死亡 (人口过少或过多) } else if (g[i][j] === 0 && neighbors === 3) { gridCopy[i][j] = 1; // 复活 (繁殖) } // neighbors === 2 || neighbors === 3 时,活细胞保持存活,无需改变 } } return gridCopy; }); setGeneration((gen) => gen + 1); setTimeout(runSimulation, speed); }, [speed]); // 开始/暂停 处理 const toggleRunning = () => { setRunning(!running); if (!running) { runningRef.current = true; runSimulation(); } }; // 单步执行 const stepForward = () => { setRunning(false); runningRef.current = true; // 临时开启以便执行一次逻辑 setGrid((g) => { const gridCopy = JSON.parse(JSON.stringify(g)); for (let i = 0; i < numRows; i++) { for (let j = 0; j < numCols; j++) { let neighbors = 0; operations.forEach(([x, y]) => { const newI = i + x; const newJ = j + y; if (newI >= 0 && newI < numRows && newJ >= 0 && newJ < numCols) { neighbors += g[newI][newJ]; } }); if (neighbors < 2 || neighbors > 3) { gridCopy[i][j] = 0; } else if (g[i][j] === 0 && neighbors === 3) { gridCopy[i][j] = 1; } } } return gridCopy; }); setGeneration((gen) => gen + 1); runningRef.current = false; // 执行完立刻关闭 }; // 随机生成 const randomize = () => { const rows = []; for (let i = 0; i < numRows; i++) { rows.push(Array.from(Array(numCols), () => (Math.random() > 0.7 ? 1 : 0))); } setGrid(rows); setGeneration(0); }; // 清空 const clearGrid = () => { setGrid(generateEmptyGrid()); setGeneration(0); setRunning(false); }; return (
Interactive Game of Life