news 2026/5/22 3:13:40

现代 C++ 助力 GOLDE:康威生命游戏模拟无限的技术突破!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
现代 C++ 助力 GOLDE:康威生命游戏模拟无限的技术突破!

1. 项目背景

发布于 2026 年 5 月 14 日,更新于 2026 年 5 月 16 日,作者使用现代 C++ 在康威生命游戏中模拟无限。[GOLDE] 是一款用于细胞自动机的编辑器和模拟器,能够瞬间模拟数万亿代。八个月前,作者在没有任何 C++ 经验的情况下开始开发它。项目最初是作者学习 OpenGL 和 C++ 基础知识的方式,随后在现代 C++ 和细胞自动机领域不断深入探索,最终 GOLDE 发展成了现在的样子。

2. HashLife 算法介绍

HashLife 将生命游戏的宇宙表示为一个记忆化的四叉树,其中每个节点都会缓存其未来多代的状态。HashLife 中的每个节点都是规范的,相同的子模式永远不会被计算两次。较大的节点代表宇宙中更大的区域,并且能够缓存更远未来的世代。具体来说,一个大小为 $2^n \times 2^n$ 个细胞的节点可以计算自身未来 $2^{n - 2}$ 代的状态。这意味着一个 $2048 \times 2048$ 的宇宙可以近乎瞬间跳跃 512 代。如果想跳得更远,GOLDE 会自动通过在边缘填充空细胞来扩大宇宙。对于像繁殖者(Breeder)这样不断扩展的模式,HashLife 可以在简单模拟前进几百代的时间内跳跃数十亿代。

3. 表示宇宙

HashLife 的实际节点级表示通过 `LifeNode` 结构体实现,其中四个指针构成了 HashLife 的四叉树结构。预先计算节点的哈希值,同时缓存 `IsEmpty` 标志,以便跳过宇宙中完全为空的大片区域。为了表示基本情况,使用两个全局定义的节点:`FalseNode` 表示一个死细胞,`TrueNode` 表示一个活细胞。这种方法使 GOLDE 未来更容易扩展以支持多状态规则。为使四叉树数据结构规范,引入了 `LifeNodeArena`,它是一个块指针分配器,以连续块的形式分配节点,保持指针稳定性。还选择了 [ankerl::unordered_dense] 作为适合工作的开放寻址哈希表。

4. 基本情况:65,536 个预计算的宇宙

使用一个 $8 \times 8$ 的基本情况来表示宇宙,HashLife 会前进 $2^{n - 2}$ 代,$8 \times 8$ 基本情况的 $n = 3$,将前进 $2^{3 - 2} = 2$ 代。目标是计算 $8 \times 8$ 区域的中心 $4 \times 4$ 网格在 2 代后的样子。一个 $4 \times 4$ 的网格包含 16 个细胞,可压缩到一个 `uint16_t` 中。由于有 16 位,每位有两种状态,总共有 $2^{16} = 65,536$ 种可能的组合,在启动时使用生命游戏规则预先计算所有 65,536 种模式。查找表中的每个结果也存储在一个 `uint16_t` 中,四个中心位位于位 0、1、4 和 5。这种方法允许轻松集成除康威生命游戏之外的其他规则。在推进 $8 \times 8$ 的基本情况时,在位级别应用 HashLife 算法,形成九个重叠的 $4 \times 4$ 窗口,每个窗口纯粹使用位操作从 $8 \times 8$ 网格中提取,九个窗口中的每个窗口都在预计算表中查找,返回该窗口中心 $2 \times 2$ 细胞的下一代状态,然后重新组合成四个重叠的 $4 \times 4$ 窗口,并再次查找,产生最终的中心 $4 \times 4$ 输出。

5. 通过抽象支持有界拓扑

GOLDE 支持有限的环形网格,HashLife 假设宇宙在所有方向上无限延伸,解决方案是对 HashLife 进行“欺骗”,在每次模拟步骤之前,将有界区域每个边缘的活细胞复制到对面边缘之外,然后 HashLife 正常运行,之后幽灵细胞被丢弃,模拟结果被渲染到屏幕上。通过 GOLDE 算法层的三元抽象 `LifeDataStructure`、`LifeAlgorithm` 和 `Topology` 轻松实现扩展点,当需要添加另一种拓扑时,只需要扩展 `Topology` 接口。`LifeDataStructure` 是契约的补充部分,HashLife 本身只看到抽象接口,交换新的拓扑不需要对算法进行任何更改。`PrepareBorderCells` 和 `CleanupBorderCells` 处理有界网格的预处理和后处理。`Log2MaxIncrement` 虚拟方法控制算法在单一步骤中可以推进的最大代数。

6. 精确跳跃 $n$ 代

HashLife 自然地以 2 的幂次推进,对于交互式编辑器,用户输入任意步长成了问题。Golly 的方法是找到能整除步长的最大 2 的幂次,分多步推进。而 GOLDE 是找到小于或等于 $n$ 的最大 2 的幂次,按这个量跳跃,从剩余步数中减去它,然后重复。这种方法并不一定比 Golly 的方法更好,GOLDE 牺牲了一些缓存效率,以换取在最多 $\log_2{n}$ 次跳跃内到达任何一代的能力。作者还与 Tomas Rokicki 讨论了结合 Golly 和 GOLDE 方法优点的算法改进,并将在 GOLDE 的开发过程中继续研究。

7. 优雅停止

为确保 HashLife 能在用户瞬间要求下停止,使用 C++20 的 `std::jthread` 和 `std::stop_token`,并贯穿于 HashLife 算法中。当模拟开始时,`std::jthread` 将停止令牌传递给 HashLife,每次递归调用时,HashLife 会快速检查停止令牌是否请求停止,若请求停止则开始提前退出。请求停止后,清除相关的缓存条目。GOLDE 支持同时运行多个模拟,为解决典型静态哈希表的问题,选择了静态的 `std::array`,每个线程拥有一个 `thread_local size_t CacheIndex`,线程根据唯一 ID 选择缓存,实现了静态缓存的效率和线程之间安全共享缓存的能力。

8. 结论

GOLDE 远不止 HashLife,多线程模拟循环将网格突变任务卸载到后台线程,同时相机继续渲染;OpenGL 渲染器通过将细胞打包到扁平纹理中,将整个宇宙批量处理为单个绘制调用;基于 ImGui 构建的 GUI 库需要在不牺牲双方优势的情况下,将其 C 风格的即时模式 API 与 GOLDE 的所有权模型进行桥接。现代 C++23 让构建这一切比 C++ 的名声所暗示的要更简洁,如果你害怕这门语言,值得再给它一次机会。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 3:12:50

scikit-learn自定义Pipeline:从接口契约到业务落地的完整实践

1. 项目概述:为什么需要自己动手定制 scikit-learn 的模型与流水线在真实的数据科学项目里,你几乎不可能靠from sklearn.ensemble import RandomForestClassifier一行代码就搞定所有事。我带过十几个工业级建模项目,从电商价格预测到医疗设备…

作者头像 李华
网站建设 2026/5/22 3:11:11

LSTM门控机制原理解析:从时间序列建模电路设计到工业落地

1. 这不是“又一个LSTM教程”:它到底在解决什么真实问题?你打开TensorFlow文档,看到tf.keras.layers.LSTM那一行,参数列表密密麻麻:units、return_sequences、dropout、recurrent_dropout……点开Stack Overflow&#…

作者头像 李华
网站建设 2026/5/22 3:04:52

如何3步完成Windows和Office永久激活:KMS_VL_ALL_AIO终极指南

如何3步完成Windows和Office永久激活:KMS_VL_ALL_AIO终极指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO是一款功能强大的智能激活脚本工具,专为Wind…

作者头像 李华
网站建设 2026/5/22 3:01:27

照片去背景的方法有哪些?一键抠图工具全面对比指南

最近有个朋友问我,想要给商品拍照换个背景,但是用PS太麻烦了,有没有更简单的办法?这个问题我相信很多人都遇到过——无论是做电商、准备证件照,还是想要美化自拍,照片去背景已经成了我们日常生活中很常见的…

作者头像 李华