
这是一个基于NKS(一种新科学)思想的3D元胞自动机模拟器。它使用 Python + Pygame + NumPy 实现,你可以在三维网格中探索简单规则如何产生复杂结构。
import pygame
import numpy as np
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import sys
# ==================== 配置参数 ====================
GRID_SIZE = 20 # 网格 20x20x20
CELL_SIZE = 0.5 # 单元格大小
CUBE_SIZE = CELL_SIZE * 0.9 # 立方体绘制大小(留间隙)
UPDATE_DELAY = 100 # 更新间隔(毫秒)
# ==================== 三维元胞自动机类 ====================
class CellularAutomaton3D:
def __init__(self, size):
self.size = size
# 随机初始化三维网格 (0 或 1)
self.grid = np.random.choice([0, 1], size=(size, size, size), p=[0.85, 0.15])
self.new_grid = np.zeros_like(self.grid)
def get_neighbor_sum(self, x, y, z):
"""计算 (x,y,z) 周围26个邻居的和(不包含自身)"""
total = 0
for i in (-1, 0, 1):
for j in (-1, 0, 1):
for k in (-1, 0, 1):
if i == 0 and j == 0 and k == 0:
continue
ni, nj, nk = x + i, y + j, z + k
if 0 <= ni < self.size and 0 <= nj < self.size and 0 <= nk < self.size:
total += self.grid[ni, nj, nk]
return total
def update(self):
"""根据 NKS 风格规则更新网格"""
for x in range(self.size):
for y in range(self.size):
for z in range(self.size):
neighbors = self.get_neighbor_sum(x, y, z)
state = self.grid[x, y, z]
# ---- NKS 风格规则(可自由修改) ----
# 规则:死细胞周围恰好有3个活细胞时诞生;活细胞周围有2或3个活细胞时存活
if state == 1:
if neighbors < 2 or neighbors > 3:
self.new_grid[x, y, z] = 0
else:
self.new_grid[x, y, z] = 1
else:
if neighbors == 3:
self.new_grid[x, y, z] = 1
else:
self.new_grid[x, y, z] = 0
self.grid, self.new_grid = self.new_grid, self.grid
self.new_grid.fill(0)
# ==================== 3D 渲染函数 ====================
def draw_cube(x, y, z, size, color):
"""在 (x,y,z) 处绘制一个彩色立方体"""
half = size / 2.0
vertices = [
[x-half, y-half, z-half], [x+half, y-half, z-half],
[x+half, y+half, z-half], [x-half, y+half, z-half],
[x-half, y-half, z+half], [x+half, y-half, z+half],
[x+half, y+half, z+half], [x-half, y+half, z+half]
]
edges = [
(0,1), (1,2), (2,3), (3,0),
(4,5), (5,6), (6,7), (7,4),
(0,4), (1,5), (2,6), (3,7)
]
glColor3f(*color)
glBegin(GL_QUADS)
# 六个面:每个面两个三角形
faces = [
(0,1,2,3), (4,5,6,7),
(0,1,5,4), (2,3,7,6),
(0,3,7,4), (1,2,6,5)
]
for face in faces:
glVertex3fv(vertices[face[0]])
glVertex3fv(vertices[face[1]])
glVertex3fv(vertices[face[2]])
glVertex3fv(vertices[face[3]])
glEnd()
glColor3f(0, 0, 0)
glBegin(GL_LINES)
for edge in edges:
glVertex3fv(vertices[edge[0]])
glVertex3fv(vertices[edge[1]])
glEnd()
def render(ca):
"""渲染整个三维网格"""
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
gluPerspective(45, 1.0, 0.1, 50.0)
glTranslatef(0.0, 0.0, -25)
glRotatef(25, 1, 0, 0)
glRotatef(-30, 0, 1, 0)
offset = (ca.size - 1) * CELL_SIZE / 2.0
for x in range(ca.size):
for y in range(ca.size):
for z in range(ca.size):
if ca.grid[x, y, z] == 1:
# 根据位置映射颜色(从蓝色渐变到红色)
r = x / float(ca.size)
g = y / float(ca.size)
b = z / float(ca.size)
draw_cube(x * CELL_SIZE - offset,
y * CELL_SIZE - offset,
z * CELL_SIZE - offset,
CUBE_SIZE, (r, g, b))
# ==================== 主程序 ====================
def main():
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
pygame.display.set_caption("3D NKS 元胞自动机 - Pygame")
glEnable(GL_DEPTH_TEST)
ca = CellularAutomaton3D(GRID_SIZE)
clock = pygame.time.Clock()
last_update = pygame.time.get_ticks()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
# 空格键:随机重置
ca.grid = np.random.choice([0, 1], size=(GRID_SIZE, GRID_SIZE, GRID_SIZE),
p=[0.85, 0.15])
elif event.key == pygame.K_r:
# R键:完全随机重置
ca.grid = np.random.choice([0, 1], size=(GRID_SIZE, GRID_SIZE, GRID_SIZE))
elif event.key == pygame.K_c:
# C键:清空
ca.grid.fill(0)
# 定时更新
now = pygame.time.get_ticks()
if now - last_update > UPDATE_DELAY:
ca.update()
last_update = now
render(ca)
pygame.display.flip()
clock.tick(30)
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
运行说明
- 安装依赖:
pip install pygame numpy PyOpenGL - 运行代码:直接执行即可
- 交互控制:
- 空格键:按85%/15%概率随机重置
- R键:完全随机重置
- C键:清空所有细胞
代码设计思路
- NKS核心思想:从极简单的局部规则出发,观察全局涌现的复杂模式。当前使用的是经典康威生命游戏规则(三维推广),你可以自由修改
update()方法中的规则逻辑,探索不同的NKS规则空间。 - 三维网格:使用
numpy存储20x20x20的0/1状态数组,邻居统计采用26邻域(周围所有相邻格子)。 - 3D渲染:基于
PyOpenGL绘制彩色立方体,颜色根据坐标位置从蓝到红渐变,方便观察结构分布。 - 性能优化:通过
UPDATE_DELAY控制演化速度,避免帧率过高导致卡顿。

398

被折叠的 条评论
为什么被折叠?



