Python生命游戏实现原理及过程解析(附源代码)


Posted in Python onAugust 01, 2019

1. 生命游戏是什么

生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞。一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;相反,如果周围活细胞过少,这个细胞会因太孤单而死去。

规则看起来很简单,但却能演绎出无穷无尽的内容。

Python生命游戏实现原理及过程解析(附源代码)

滑翔者:每4个回合"它"会向右下角走一格。虽然细胞早就是不同的细胞了,但它能保持原本的形态。

Python生命游戏实现原理及过程解析(附源代码)

轻量级飞船:它的周期是4,每2个回合会向右边走一格。

Python生命游戏实现原理及过程解析(附源代码)

脉冲星:它的周期为3,看起来像一颗周期爆发的星星。

Python生命游戏实现原理及过程解析(附源代码)

更复杂的图案。

来体会一下这些作品的脑洞以及震撼:

史诗般的生命游戏 http://www.iqiyi.com/w_19rsq435c9.html

用生命游戏实现生命游戏:http://www.bilibili.com/video/av616329/index.html

2. Console版:一个简单的Python实现

生命游戏的规则其实很简单。我们可以把计算机中的宇宙想象成是一堆方格子构成的封闭空间,尺寸为N的空间就有N*N个格子。

而每一个格子都可以看成是一个生命体,每个生命都有生和死两种状态,如果该格子生就显示蓝色,死则显示白色。每一个格子旁边都有邻居格子存在,如果我们把3*3的9个格子构成的正方形看成一个基本单位的话,那么这个正方形中心的格子的邻居就是它旁边的8个格子。

每个格子的生死遵循下面的原则:

1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。

2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;

3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)

设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。

我们用#代表活的细胞,空格表示死的细胞,那么我们可以用控制台打印字符、清屏来模拟生命游戏。我的代码在github上:

https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLife.py

游戏世界尺寸为60x20,随机生成初始状态,循环边界,按任意键进入下一帧,q退出。

单纯的看这段程序,好像并没有什么问题,代码逻辑正确、清晰。

效果图:

Python生命游戏实现原理及过程解析(附源代码)

3. Python列表生成式

我们来尝试一些python的高级特性,比如列表生成式。

例如,在生成初始值时,我们一般这样写:

screen = []
width = 60
height = 20
def Init():
 for i in range(height):
  line = []
  for j in range(width):
   if random.random() > 0.8:
    line.append('#')
   else:
    line.append(' ')
  screen.append(line)

如果用列表生成式,我们可以这样写:

def Init():
  global screen
  screen = [['#' if random.random() > 0.8 else ' ' for i in range(width)] for j in range(height)]

注意这里必须用global声明,否则screen将默认作为函数内的局部变量。这里用了两层列表生成式来生成一个二维数组。

列表生成式很好很强大,如果用好能大大提高效率。但会牺牲一定的可读性,如果单个表达式写的过于复杂,那就变成write-only了。尤其是在团队开发情况下,可读性日益重要。

重写后的代码:

https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLife.1.py

如果仅仅是作为练习,这样就已经足够好了,简洁易读。

4. 重构:面向对象与重用

可是我们还不能满足,我们来给生命插上面向对象的翅膀,在模块化的天空中翱翔。对,就是让他跟别的模块搞对象!

先来定义一个类GameOfLifeWorld,之前那些丑陋的全局变量,让他们统统变成成员变量,再也不能在外兴风作浪。

class GameOfLifeWorld:

 width = 100
 height = 100
 cells = []
…略

然后把UI层剥离,只保留游戏的核心逻辑。

代码:

https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLifeWorld.py

5. GUI:Tkinter的调用

有了上一步的铺垫,我们终于可以让Tkinter粉墨登场了。Tkinter是著名的UI库,Python自带的Tkinter是一个精简版,不过也够我们用的了。

我们这里用到的主要是Canvas,Button控件。Canvas画布用来绘制游戏区,Button用来交互。

代码:

https://github.com/Pleiades0428/GameOfLife/blob/master/Demo/gameOfLifeWorld.py

效果:

Python生命游戏实现原理及过程解析(附源代码)

以上就是这样,项目我还会继续改进,希望大家喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
测试、预发布后用python检测网页是否有日常链接
Jun 03 Python
Python 中 Meta Classes详解
Feb 13 Python
python3 图片referer防盗链的实现方法
Mar 12 Python
基于Python pip用国内镜像下载的方法
Jun 12 Python
python求最大连续子数组的和
Jul 07 Python
python爬虫之线程池和进程池功能与用法详解
Aug 02 Python
Python+pyplot绘制带文本标注的柱状图方法
Jul 08 Python
python程序中的线程操作 concurrent模块使用详解
Sep 23 Python
jupyter notebook参数化运行python方式
Apr 10 Python
python批量生成条形码的示例
Oct 10 Python
python自动化发送邮件实例讲解
Jan 04 Python
python 指定源路径来解决import问题的操作
Mar 04 Python
Python中list的交、并、差集获取方法示例
Aug 01 #Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
Aug 01 #Python
Python使用Pandas对csv文件进行数据处理的方法
Aug 01 #Python
python使用writerows写csv文件产生多余空行的处理方法
Aug 01 #Python
python psutil模块使用方法解析
Aug 01 #Python
python读写csv文件并增加行列的实例代码
Aug 01 #Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
Aug 01 #Python
You might like
PHP学习之PHP表达式
2006/10/09 PHP
php中调用其他系统http接口的方法说明
2014/02/28 PHP
php中替换字符串中的空格为逗号','的方法
2014/06/09 PHP
CodeIgniter表单验证方法实例详解
2016/03/03 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
php微信公众号开发模式详解
2016/11/28 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
Laravel框架Blade模板简介及模板继承用法分析
2019/12/03 PHP
jQuery中json对象的复制方式介绍(数组及对象)
2013/06/08 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
2015/03/04 Javascript
javascript实现checkBox的全选,反选与赋值
2015/03/12 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
jQuery实现右下角可缩放大小的层完整实例
2016/06/20 Javascript
利用Angularjs和原生JS分别实现动态效果的输入框
2016/09/01 Javascript
基于elementUI实现图片预览组件的示例代码
2019/03/31 Javascript
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
2019/07/10 Javascript
vue 解决数组赋值无法渲染在页面的问题
2019/10/28 Javascript
微信小程序tab左右滑动切换功能的实现代码
2021/02/08 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
Python如何import文件夹下的文件(实现方法)
2017/01/24 Python
python 读取excel文件生成sql文件实例详解
2017/05/12 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
2020/05/20 Python
Python docutils文档编译过程方法解析
2020/06/23 Python
Python变量及数据类型用法原理汇总
2020/08/06 Python
Microsoft新加坡官方网站:购买微软最新软件和技术产品
2016/10/28 全球购物
Myprotein芬兰官网:欧洲第一运动营养品牌
2019/05/05 全球购物
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
室内设计专业个人的自我评价
2013/10/19 职场文书
高三政治教学反思
2014/02/06 职场文书
批评与自我批评材料
2014/02/15 职场文书
房产转让协议书(2014版)
2014/09/30 职场文书
老员工辞职信范文
2015/05/12 职场文书
幼儿园园务工作总结2015
2015/05/18 职场文书
2015年教务主任工作总结
2015/07/22 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang