这次我们使用 Python 来实现生命游戏,这是一种简单的元胞自动机。基于一定规则,程序可以自动从当前状态推演到下一状态。制作的成品如下:

先来说说生命游戏的规则:

在生命游戏中,每个单元格有两种状态,生与死。在我们的实现中,黄色的单元格代表活着的细胞,红色单元格表示死亡的细胞。而每一个细胞的下一状态,是由该细胞及周围的八个细胞的当前状态决定的。

具体而言:

当前细胞为活细胞

  1. 周围有两个或者三个活细胞,下一世代,该细胞仍然活着。
  2. 周围少于两个活细胞,该细胞死于孤立。
  3. 周围多于三个活细胞,该细胞死于拥挤。

当前细胞为死细胞

  • 周围恰好三个活细胞,下一世代,活细胞将繁殖到该单元格。

所需模块

无需安装的标准库:

  • argparse(命令行参数)
  • enum(枚举)

第三方库:

  • numpy
  • matplotlib

导入模块:

# 关注微信公众号:Python高效编程,后台回复`2019527`,获取源代码。
import argparse
from enum import IntEnum
import matplotlib.pyplot as plt
import matplotlib.animation as animation  # 制作动图
import numpy as np

编程要点

首先,我们要知道细胞的生存空间是 N * N 的方阵,每个细胞都有两种状态:on, off。on 为 255,off 为 0。我们使用 numpy 产生 N * N 的方阵。np.random.choice 是在 State.on 和 State.off ,等概率随机抽取一个元素构造 N * N 的方阵。

class State(IntEnum):on = 255off = 0def random_data(length = 4, seed = 420) -> np.array:np.random.seed(seed)return np.random.choice([State.off, State.on], size=(length, length), p=[0.5, 0.5])

其次我们要明白如何计算细胞周围活细胞的个数,尤其是边界一圈的细胞。我们可以采用余数的方式,假设棋盘大小为 9 * 9,那么对于左右边界而言,左边界的左边一个元素的计算方式: - 1 % 9 = 8,自动折到右边界上。将细胞周围八个单元格的数值加起来,除以 255,就可以得到细胞周围活细胞的个数。

def _count(data, row, col):shape = data.shape[0]up = (row - 1) % shapedown = (row + 1) % shaperight = (col + 1) % shapeleft = (col - 1) % shapereturn (data[up, right] + data[up, left] +data[down, right] + data[down, left] +data[row, right] + data[row, left] +data[up, col] + data[down, col]) // 255

接下来是对规则的翻译,即根据当前世代的状态,推演出下一世代,细胞的状态。initial 为当前世代的矩阵,data为下一世代的矩阵,我们根据 initial 的数值,计算出 data 的数值。total 为周围活细胞的个数,如果当前为活细胞,total 大于三或者小于二,下一世代就会死去。如果当前为死细胞,total 等于三,下一世代活细胞就会繁殖到该单元格上。

def count(initial, data, row, col):total = _count(initial, row, col)if initial[row, col]:if (total < 2) or (total > 3):data[row, col] = State.offelse:if total == 3:data[row, col] = State.on

接下来是制作动图的过程,前面几行是绘图的基本操作。之后,我们使用到了 matplotlib.animation 的方法。其中,FuncAnimation 接受的参数含义:fig 为图像句柄,generate 函数是我们更新每一帧图像所需数据的函数,下面会有介绍,fargs 为 genrate 函数的除去第一个参数的其他参数,第一个参数由 FuncAnimation 指定 framenum(帧数) 传给 generate 函数。frames 是帧数,interval 是更新图像间隔,save_count 为从帧到缓存的值的数量。

如果指定保存路径(html),则保存为 html 动画。

# 关注微信公众号:Python高效编程,后台回复`2019527`,获取源代码。
def update(data, save_name):update_interval = 50fig, ax = plt.subplots()ax.set_xticks([])ax.set_yticks([])img = ax.imshow(data, cmap='autumn', interpolation='nearest')ani = animation.FuncAnimation(fig, generate, fargs=(img, plt, data),frames=20,interval=update_interval,save_count=50)if save_name:ani.save(save_name, fps=30, extra_args=['-vcodec', 'libx264'])plt.show()

下面我们来看 generate 函数,NUM 为当迭代次数,frame_num 接收来自 FuncAnimation 的帧数。通过嵌套的 for 循环,我们逐个地更新方阵中各元素的状态。

NUM = 0
# 关注微信公众号:Python高效编程,后台回复`2019527`,获取源代码。
def generate(frame_num, img, plt, initial):global NUMNUM += 1plt.title(f'{NUM} generation')data = initial.copy()rows, cols = data.shapefor row in range(rows):for col in range(cols):count(initial, data, row, col)img.set_data(data)initial[:] = data[:]return img

最后,我们可以通过命令行参数,运行我们的程序:

– size 参数为棋盘大小,–seed 为随机种子,用于产生不同的随机方阵。

python conway.py --size 50 --seed 18

高斯帕滑翔机枪(Gosper Glider Gun)

可将 --gosper 更改为 --glider 滑翔机。–save 为动图保存的地址。

python conway.py --size 80 --gosper --save gosper.html


关注微信公众号:Python高效编程,后台回复2019527,获取源代码。

Python 实现生命游戏相关推荐

  1. 康威生命游戏java_Java Python 康威生命游戏 - 命令行版

    Java & Python 康威生命游戏 - 命令行版(2020年7月23日) 制作背景 高二的时候看霍金的<大设计>最后几页的时候看到里面提到了康威生命游戏,介绍了它的规则,感觉 ...

  2. Python - 康威生命游戏Conway's game of life

    使用python实现康威生命游戏Conway's game of life 参考<python极客项目编程> 游戏规则: 任何四周邻居存活数少于两个的存活网格将死亡,因为人口稀少. 任何四 ...

  3. Python实现生命游戏

    作者 | 借我一生执拗 来源 | Python高效编程 这次我们使用 Python 来实现生命游戏,这是一种简单的元胞自动机.基于一定规则,程序可以自动从当前状态推演到下一状态.制作的成品如下: 先来 ...

  4. Python实现生命游戏(Game of Life)

    生命游戏的算法就不多解释了,百度一下介绍随处可见. 因为网上大多数版本都是基于pygame,matlab等外部库实现的,二维数组大多是用numpy,使用起来学习成本比较高,所以闲暇之余写一个不用外部依 ...

  5. python游戏后端_Python实现生命游戏

    1. 生命游戏是什么 生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个 ...

  6. 用pygame做一个简单的python小游戏---生命游戏

    用pygame做一个简单的python小游戏-生命游戏 生命游戏(Game of Life) 生命游戏(Game of Life)是剑桥大学约翰·何顿·康威(John Horton Conway)教授 ...

  7. python做的大型游戏_Python实现数据量较大的生命游戏

    我现在要用串行的方法实现一个生命游戏,这个生命游戏是在一个100000 x 100000的棋盘上,并且繁衍500代.我选择用list形成一个二维数组来装这个棋盘上的数据,可是程序运行到一半,报错说me ...

  8. Python | 实现简单的康威生命游戏

    康威生命游戏是由英国教授John Horton Conway提出的一种生命仿真游戏.其具体的形式是,所有的细胞生活在一个二维平面上,一个细胞在下一个时刻的生存状态取决于当前时刻周围的各个细胞的生存状态 ...

  9. 复杂性思维中文第二版 六、生命游戏

    六.生命游戏 原文:Chapter 6 Game of Life 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 在本章中,我们考虑二维细胞自动机,特别是 John Conway ...

最新文章

  1. [YTU]_2865( 结构体--日期计算)
  2. org.apache.jasper.JasperException: Unable to compile class for JSP
  3. .Net Core SignalR 初体验
  4. mysql 触发器计算总价,mysql’插入’触发器根据其他字段计算字段
  5. minio 授予永久访问权限_应对 iOS 14 权限管理 应用手把手教你打开“所有照片”权限...
  6. 数据增长浪潮下,PCIe 6.0的问与Rambus的答
  7. editplus设置不生成备份文件_删库不跑路,手把手教你MySQL数据恢复
  8. @ConfigurationProperties 在IDEA中出现红色波浪线问题
  9. 爬虫headers参数
  10. Windows环境下使用UHD PythonAPI开发USRP X310
  11. windows压缩包 无法在Linux上打开
  12. python常用工具类
  13. 验证码输入错误怎么再次刷新验证码
  14. 极验第四代滑块验证码破解(四):请求分析及加密参数破解
  15. 一个简单有效的手写识别引擎
  16. 电子鼻气味扫描技术在食品检测中的作用
  17. python 宏使用详解
  18. 整除光棍 分数 20作者 翁恺单位 浙江大学
  19. 微信公开课2019-张小龙
  20. TCP通信过程详解以及tcp长连接和短连接

热门文章

  1. SpringMVC中使用hibernate-validator的坑
  2. Crypto one-time-pad
  3. SyntaxError: Non-UTF-8 code starting with '\xb5' in file“问题解决办法
  4. scrapy使用用Xpath提取深层标签
  5. 大数据招聘,我就这样被算法选中
  6. 前端获取当前服务器时间,不使用客户端电脑时间
  7. 台式计算机屏幕扩展,台式机屏幕如何扩展
  8. POJ:1182 食物链(带权并查集)
  9. Material Design(三)--暗色主题设计
  10. [保姆级教程]解决Centos 8下无法更新的问题 (附无痕迁徙到Rocky Linux的方法)