一、简单元胞自动机简介
设定指定空间中的每个细胞的初始状态后依据一定生存规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。
二、游戏规则
(一)对于确定细胞的周边范围,我们将其定义为细胞八方位的邻近单元;
(二)每个细胞均有生与死两种状态;
(三)细胞生死遵循如下规则:
①如果一个细胞周围有3个细胞为生,则该细胞为生(即该细胞若原先为死,则转为生;若原先为生,则保持不变);
②如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
③在其他情况下,该细胞为死(即该细胞若原先为生,则转为死;若原先为死,则保持不变);
④对于环境边界(即矩阵边缘行列),四角的细胞只有3个邻近细胞;对于边界直线细胞只有5个邻近细胞。
三、实现代码
# cellular (元胞自动机)
# 2022年12月03日
# 库包导入部分
import random
import copy
# 函数体部分
# 生命空间初始化函数
# 形参height表示生命空间高,width表示生命空间宽,life_prob表示活细胞随机生成概率(0<life_prob<1)
# *表示细胞存活,‘ ’(空格)表示细胞死亡
def life_init(height,width,life_prob):
lifeSpace = []
for i in range(height):
row = []
for j in range(width):
if random.random() < life_prob:
row.append('*')
else:
row.append(' ')
lifeSpace.append(row)
return lifeSpace
# 细胞状态可视化函数
# 生存环境边界表示为”|“
def print_screen(lifeSpace):
height = len(lifeSpace)
width = len(lifeSpace[0])
for i in range(height):
print("|", end='')
for j in range(width):
print(lifeSpace[i][j], end='')
print("|")
# 计算相邻细胞中活细胞的数目
def get_near_by_cells_count(lifeSpace, i, j):
height = len(lifeSpace)
width = len(lifeSpace[0])
# count为邻近细胞的或细胞数目
count = 0
if i==0:
if j==0:
for r in range(2):
for c in range(2):
if r==0 and c==0:
continue
else:
if lifeSpace[i+r][j+c] == '*':
count += 1
elif j==width-1:
for r in range(2):
for c in range(2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j - c] == '*':
count += 1
else:
for r in range(0,2):
for c in range(-1,2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j + c] == '*':
count += 1
elif i==height-1:
if j==0:
for r in range(2):
for c in range(2):
if r==0 and c==0:
continue
else:
if lifeSpace[i-r][j+c] == '*':
count += 1
elif j==width-1:
for r in range(2):
for c in range(2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i - r][j - c] == '*':
count += 1
else:
for r in range(-1,1):
for c in range(-1,2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j + c] == '*':
count += 1
else:
if j == 0:
for r in range(-1,2):
for c in range(0,2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j + c] == '*':
count += 1
elif j == width-1:
for r in range(-1,2):
for c in range(-1,1):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j + c] == '*':
count += 1
else:
for r in range(-1,2):
for c in range(-1,2):
if r == 0 and c == 0:
continue
else:
if lifeSpace[i + r][j + c] == '*':
count += 1
return count
# 更新各细胞状态
def update(lifeSpace):
height = len(lifeSpace)
width = len(lifeSpace[0])
# 创建新的细胞生存环境
# 深度拷贝copy.deepcopy—无论列表多少层,得到的新列表都是和老列表无关
# 单层拷贝List.copy—只能实现第一层的复制
new_lifeSpace = copy.deepcopy(lifeSpace)
for i in range(height):
for j in range(width):
if get_near_by_cells_count(lifeSpace,i,j) == 3:
new_lifeSpace[i][j] = '*'
elif get_near_by_cells_count(lifeSpace,i,j) == 2:
new_lifeSpace[i][j] = lifeSpace[i][j]
else:
new_lifeSpace[i][j] = ' '
return new_lifeSpace
# 生存环境中全体细胞生存状态检测(若前后两次不变则退出游戏)
def is_state_same(lifeSpace, new_lifeSpace):
height = len(lifeSpace)
width = len(lifeSpace[0])
for i in range(height):
for j in range(width):
if lifeSpace[i][j] != new_lifeSpace[i][j]:
return False
return True
# 主函数体部分(运行代码)
if __name__ == '__main__':
height = eval(input("请输入细胞生存环境空间的高:"))
width = eval(input("请输入细胞生存环境空间的宽:"))
life_prob = eval(input("请输入活细胞的随机生成概率:"))
# 记录次数
n = 0
old = life_init(height, width, life_prob)
print('第 0 次迭代')
print_screen(old)
while True:
n = n + 1
new = update(old)
if is_state_same(old, new):
print('状态无更新,游戏结束!')
break
else:
print(f'第 {n} 次迭代')
print_screen(new)
old = new
r = input('按q键结束,其他键继续游戏:')
if r == 'q':
print("游戏结束!")
break
四、游戏展示
扫描二维码关注公众号,回复:
15260515 查看本文章
五、附 录
Python语言程序设计/嵩天老师—北京理工大学(MOOC)简单笔记:(资源永久免费)
简单的Python基础编程学习记录,学习课程源于北京理工大学嵩天老师的《Python语言基础编程》课程-算法与数据结构文档类资源-CSDN下载