康威生命游戏:用 p5.js 实现 Cellular Automata 元胞自动机(Coding Challenge 85 全解析)

发布时间:2026/10/12 15:02:16

康威生命游戏:用 p5.js 实现 Cellular Automata 元胞自动机(Coding Challenge 85 全解析) 教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载康威生命游戏Conways Game of Life是元胞自动机Cellular Automata最经典的入门案例也是 Coding Challenge #85 的核心主题。本文以该编码挑战为骨架完整讲解规则、二维数组建模、邻居计数与 p5.js 渲染实现并结合仓库中的 sketch.js 与 Processing 版本源码逐行剖析读完你将能独立写出可运行的生命游戏模拟器并理解所有元胞自动机的通用编程模式。一、挑战概述一句话的目标原文档_CodingChallenges/085-the-game-of-life.md对本次挑战的定位非常简洁In this coding challenge, I attempt to code Conways Game of Life cellular automata simulation in JavaScript using the p5.js library.即使用 p5.js 库用 JavaScript 编写康威生命游戏的元胞自动机模拟。挑战视频编号 85发布于 2017-12-11front matter 中的date: 2017-12-11对应仓库目录为CC_085_The_Game_of_Life包含 P5index.htmlsketch.js与 ProcessingCC_085_The_Game_of_Life.pde两套完整实现代码结构几乎一一对应便于跨语言对照学习。二、康威生命游戏的四大规则生命游戏是一个二维的、基于网格grid的元胞自动机每个格子称为一个细胞cell只有两种状态——存活1白色或死亡0黑色。时间按代generation离散推进每一代的状态只由上一代自身状态 周围 8 个邻居的存活数量决定。四条规则这也是后续代码next[i][j]计算的直接依据孤单致死Underpopulation存活细胞若周围存活邻居数neighbors 2下一代死亡。过密致死Overpopulation存活细胞若周围存活邻居数neighbors 3下一代死亡。存活Survival存活细胞若周围存活邻居数neighbors 2或neighbors 3下一代继续存活。繁殖Birth / Reproduction死亡细胞若周围存活邻居数恰好为neighbors 3下一代变为存活。在 sketch.js 中这四条规则被浓缩为两行判断if (state 0 neighbors 3) { next[i][j] 1; // 繁殖死细胞恰好 3 个活邻居 → 复活 } else if (state 1 (neighbors 2 || neighbors 3)) { next[i][j] 0; // 孤单致死 / 过密致死 } else { next[i][j] state; // 其余情况2 或 3 个邻居保持原状态 }Processing 版本CC_085_The_Game_of_Life.pde逻辑完全一致只是把grid换成int[][]、next换成int[][]可见这套规则与语言无关是整个模拟的引擎。规则出处参考康威生命游戏维基百科条目 与 《数学游戏》专栏Scientific American, 1970 年 10 月这两条外部资料被原文档收录在 front matter 的links字段中。三、用二维数组建模网格生命游戏的核心数据结构是二维数组。由于 JavaScript 原生不支持真正的多维数组挑战中专门封装了一个make2DArray(cols, rows)工厂函数来创建数组的数组function make2DArray(cols, rows) { let arr new Array(cols); // 外层列 for (let i 0; i arr.length; i) { arr[i] new Array(rows); // 内层行 } return arr; }对应的全局变量与画布参数sketch.js#L16-L19变量含义取值resolution每个细胞的边长像素10cols列数 width / resolution画布 600px →60rows行数 height / resolution画布 400px →40grid二维数组grid[i][j]取 0 或 1初始随机填充在setup()中画布被设为createCanvas(600, 400)因此网格是60 列 × 40 行、共 2400 个细胞。随后用嵌套for循环对每个细胞做随机初始化grid[i][j] floor(random(2))即以 50% 概率随机生成初始存活/死亡分布——这也是观察生命游戏从混沌演化出稳定图案的经典起点。前置知识如果不熟悉二维数组的创建、初始化与嵌套循环遍历可先阅读仓库内配套教程 《2D Arrays in JavaScript》另外原文档还关联了更早一期的《The Game of Life》Processing 版讲解_more/archive/nature-of-code/7-Cellular-Automata/7.3-The-Game-of-Life.md可对照理解同一算法在 Java 与 JavaScript 中的差异。四、邻居计数与环形环绕边界生命游戏每一代都要为每个细胞统计其8 个邻居中的存活数量。countNeighbors函数用两层for循环遍历i -1..1、j -1..1的 3×3 邻域关键技巧在于边界处理function countNeighbors(grid, x, y) { let sum 0; for (let i -1; i 2; i) { for (let j -1; j 2; j) { let col (x i cols) % cols; // 列方向环绕wrapping let row (y j rows) % rows; // 行方向环绕 sum grid[col][row]; } } sum - grid[x][y]; // 减去自己避免把自己算进邻居 return sum; }这里有两个值得深究的实现细节取模运算实现环形世界torus(x i cols) % cols让网格左、右、上、下边缘互相连通——最左列细胞可以看到最右列的邻居最顶行能看到最底行。这是很多生命游戏实现默认采用的无限平面近似策略避免边界细胞因邻居不足而产生失真。关于取模运算本身的原理原文档关联了 Golan Levin 的 《The Modulo Operator》 客座教程。先加后减避免分支判断循环把 3×3 共 9 个格子的值全部累加包括细胞自己最后用sum - grid[x][y]一次性剔除自身比在循环内加if判断更简洁高效。五、双缓冲为什么必须用next数组这是元胞自动机最容易踩的坑也是本挑战代码中最关键的设计决策。draw()中没有直接修改grid而是先新建一个空的next数组把根据规则计算出的下一代状态全部写入next等整个网格计算完毕后才执行grid next完成整体替换sketch.js#L49-L69。原因在于元胞自动机的状态更新必须同步进行。每个细胞的新状态只能由上一代的全局状态决定如果边遍历边修改grid那么右侧、下方尚未遍历的细胞就会读到已经更新过的邻居导致同一代内传播错误演化结果完全失真。next数组相当于一个缓冲区buffer保证所有细胞都基于同一代快照计算——这也是并行计算中双缓冲double buffering思想的直观体现。渲染部分同样在draw()中完成先background(0)清屏再遍历所有细胞仅对存活细胞grid[i][j] 1绘制白色方块且每格缩小 1 像素rect(x, y, resolution - 1, resolution - 1)以形成网格线background(0); for (let i 0; i cols; i) { for (let j 0; j rows; j) { let x i * resolution; let y j * resolution; if (grid[i][j] 1) { fill(255); stroke(0); rect(x, y, resolution - 1, resolution - 1); } } }六、运行方式P5 网页版与 Processing 版仓库为同一挑战提供了两种运行入口代码逻辑完全同构1. p5.js 网页版推荐零依赖入口文件P5/index.html逻辑文件P5/sketch.jsindex.html通过 CDN 引入 p5.js 1.4.1再加载本地sketch.jsscript typetext/javascript srchttps://cdn.jsdelivr.net/npm/p51.4.1/lib/p5.min.js/script script typetext/javascript srcsketch.js/script直接浏览器打开该 HTML 文件即可看到生命游戏在 600×400 画布上自动演化。2. ProcessingJava版入口文件CC_085_The_Game_of_Life.pde.pde文件用 Processing IDE或processing-java命令行工具打开运行。其源码注释明确标注Originally written using p5.js两种语言的函数一一对应createCanvas↔sizefloor(random(2))↔floor(random(2))background/fill/stroke/rect均同名非常适合作为同一算法、两种语言的对照练习。提示Processing 版同样实现了环形边界(x i cols) % cols与双缓冲int[][] next new int[cols][rows];后grid next;可逐行与 p5.js 版对比加深对语言差异动态类型 vs 静态类型、数组声明方式的理解。七、扩展玩法与社区贡献生命游戏的价值远不止跑起来。原文档的 front matter 中收录了contributions字段记录了社区在本次挑战基础上衍生的大量变体可作为功能扩展的直接灵感清单交互式网格Knut Jackowski 的 editable grid、Ayush Koul 的 Editable, Playable and with brief info、Sungyoung Kim 的 with user interactions!——用鼠标点击绘制/擦除细胞让用户手动摆放图案后再启动演化界面与框架变体React.js 版Fi Graham、Saswat Dash、Melissa Longenberger、vanilla JS 版Shekhar Tyagi、LÖVE/Lua 版vinnyI-afk、Pygame/Python 版Pathik Ghugare、C 语言浏览器版Imtiaz Kabir、terminal commands版Andrew Y视觉效果升级Colorful Game of LifeJamie McCrory、The Greg of LifeGreg Kreisman、Life Game CanvasRyosuke Osaki算法与数据结构优化Rick Sidwell 的 Yet Another Life 使用**稀疏数组sparse arrays**大幅降低大网格的内存占用——从源码结构看这是针对全量二维数组方案的一种典型性能优化方向创意衍生Photo to cellular automataLenoir Christopher把照片像素映射为初始细胞状态、Game of Life With PatternsHoangTran内置经典图案库滑翔机、振荡器等。这些贡献分布在各社区作者的独立仓库中仓库本体的contributions列表_CodingChallenges/085-the-game-of-life.md 的 front matter保留了完整作者与来源链接便于检索和借鉴。八、小结从生命游戏到元胞自动机通过本挑战你实际上掌握了任意二维元胞自动机的通用编程骨架建模用make2DArray构造二维数组表示网格状态演化countNeighbors统计邻域用规则函数生成下一代同步更新next缓冲区 grid next保证一代一快照渲染p5.js 的rect/fill把数组状态可视化。康威生命游戏只是这个框架下规则最经典的一个实例——把countNeighbors换成左右邻居之和就得到一维规则 30/90初等元胞自动机换成连续数值与距离加权就得到 Reaction-Diffusion、流场等更复杂的模拟仓库中的 CC_013_ReactionDiffusion 正是同一编程思路的进阶挑战。理解本次的四个规则与双缓冲机制你就拥有了探索整个元胞自动机家族的第一把钥匙。赞分享教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载相关推荐用 p5.js 复刻 Agar.io 基础游戏机制Coding Challenge 32.1 全解析用 p5.js 复刻 Agar.io 基础游戏机制Coding Challenge 32.1 全解析 这篇技术指南围绕 Coding TrainThe Co教程文档示例工程用 Yew 实现康威生命游戏从细胞自动机核心到交互式 Web 界面用 Yew 实现康威生命游戏从细胞自动机核心到交互式 Web 界面 本篇技术指南以 Yew 官方示例 examples/game_of_life https:前端Web框架用 p5.js 复刻经典扫雷游戏Minesweeper Coding Challenge 71 源码级实战解析用 p5.js 复刻经典扫雷游戏Minesweeper Coding Challenge 71 源码级实战解析 导读 本文基于 Coding TrainTh教程文档示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/12 15:02:16

深度图与彩色图人脸检测:多模态融合代码实战与避坑指南

简介:这份资源面向计算机视觉初学者与开发者,提供利用深度图像与彩色图像进行人脸检测的完整代码实践,数据源自微软Kinect传感器,可同时获取人体3D彩色与深度信息,适用于安全监控、虚拟现实等场景下的检测研究。压缩包…

2026/10/12 15:02:16

从AnyPS5看如何在PC上复刻主机级游戏体验:兼容层与系统调优实践

1. 项目概述与核心需求解析 “AnyPS5”——单看这个名字,你可能会以为这又是一个折腾主机模拟器的项目。但玩过一圈你会发现,它真正想解决的问题是: 如何在一台通用 x86_64 架构的 PC 上,构建出一个在功能、性能、使用体验上都尽…

2026/10/12 16:07:38

电力系统机组组合优化实战:MILP建模与Python求解全指南

简介:一套MATLAB电力系统机组组合优化实践资料,面向电力系统调度、运行规划研究人员及相关专业学生,重点覆盖机组启停决策、最优出力分配与多类约束处理。压缩包共10个文件,以Excel结果表格、Visio图表、MATLAB脚本和Word说明文档…

2026/10/12 16:07:38

RAG知识库构建指南:从向量化到Agent集成

1. 为什么 Agent 场景里先打 RAG 基础做 Lang-Agent 系列做到第 5 篇,前面已经聊过 Agent 的基本框架、工具调用、记忆管理。这一篇开始进入一个绕不开的核心环节:RAG,也就是检索增强生成。我在实际项目里见过不少同学一上来就让 Agent 直接对…

2026/10/12 16:07:38

仿生学信息素网络:多智能体上下文管理的突破口

1. 先别急着调 Prompt:我为什么盯上了一个仿生学方案如果你也维护过不止两三个智能体协作的复杂任务,大概率会撞上这样一个场景:Agent 一多,上下文就开始“膨胀”和“稀释”。我最早是在一套模拟三个智能体协作的流程里被逼到墙角…

2026/10/12 16:07:38

B站动漫爬虫全流程:从requests+xpath采集到可视化看板

简介:面向Python爬虫与数据分析初学者的B站动漫数据项目,以哔哩哔哩番剧为对象,演示从总榜爬取动漫列表、访问详情页抓取追番人数与评分,再到数据清洗、统计分析与可视化的完整流程,适合作为爬虫与数据分析方向的入门实…

2026/10/12 16:02:36

2026年围棋赛事日程全解析:赛程结构与观赛指南

2026年主要围棋赛事的日程,最近陆续在各大赛体系里露出轮廓了。每年这个时候,棋迷圈都会掀起一轮“赛程整理热”,有人拿日历逐个标注,有人守着官方通知蹲更新。今年这份排期比往年更满、更挤,年初就有多项国际赛事扎堆…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑