TypeScript实现的康威生命游戏为何在约5代后停止演化?
修复康威生命游戏的两个关键问题
我帮你找到了导致游戏提前稳定的两个核心问题,修改后就能正常运行康威生命游戏的完整规则了:
1. 邻居索引计算错误(最致命的bug)
在loadNeighborhood2d函数里,你计算细胞索引时错误地使用了高度ca.h,而正确的应该是宽度ca.w。因为每个行包含w个细胞,第y行第x列的索引公式是y * w + x,用h会导致加载完全错误的邻居,规则计算自然失效。
修正后的loadNeighborhood2d函数关键部分:
function loadNeighborhood2d(ca: CA2D, x: number, y: number) { // ... 省略x1/x2/x3和y1/y2/y3的计算逻辑 ... // 修正索引计算:把ca.h改成ca.w let i00 = y1 * ca.w + x1; let i01 = y1 * ca.w + x2; let i02 = y1 * ca.w + x3; let i10 = y2 * ca.w + x1; let i11 = y2 * ca.w + x2; let i12 = y2 * ca.w + x3; let i20 = y3 * ca.w + x1; let i21 = y3 * ca.w + x2; let i22 = y3 * ca.w + x3; // ... 后续赋值逻辑不变 ... }
2. 规则逻辑错误
你的规则里有一处不符合康威生命游戏的定义:
- 第二个规则中,死细胞复活时你返回了
0,但活细胞的状态值是1,所以应该返回1才能让死细胞变成活的; - 第三个规则中,死细胞的情况应该返回
0保持死亡状态,而不是-1(虽然当前代码可能因为默认值巧合工作,但明确返回更稳妥)。
修正后的规则:
move: [ (n: Uint8ClampedArray) => { const sum = _.sum(n) const isLive = n[4] === 1 // 活细胞有2或3个活邻居 → 存活(sum = 自己1 + 邻居2/3 → sum=3或4) if (isLive && (sum === 3 || sum === 4)) { return 1 } return -1 }, (n: Uint8ClampedArray) => { const sum = _.sum(n) const isDead = n[4] === 0 // 死细胞有3个活邻居 → 复活(sum=3,因为自己是0) if (isDead && sum === 3) { return 1 // 这里从0改为1 } return -1 }, (n: Uint8ClampedArray) => { // 其他情况:活细胞死亡,死细胞保持死亡 return n[4] === 1 ? 0 : 0 }, ],
验证修改效果
修改完成后,重新运行你的测试代码:
npm run test node dist.test/test
生成的GIF应该能正确展示康威生命游戏的演化过程,比如滑翔机移动、振荡器周期变化等经典模式,不会过早稳定。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

