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抓取电影天堂电影信息的代码
Apr 07 Python
浅析Python中的getattr(),setattr(),delattr(),hasattr()
Jun 14 Python
详解Python中类的定义与使用
Apr 11 Python
Python3网络爬虫之使用User Agent和代理IP隐藏身份
Nov 23 Python
Python实现邮件的批量发送的示例代码
Jan 23 Python
Python断言assert的用法代码解析
Feb 03 Python
Python代码块批量添加Tab缩进的方法
Jun 25 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
Aug 09 Python
python实现宿舍管理系统
Nov 22 Python
Python 元组拆包示例(Tuple Unpacking)
Dec 24 Python
Python用类实现扑克牌发牌的示例代码
Jun 01 Python
Python with语句用法原理详解
Jul 03 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
动漫女神老婆无限好,但日本女生可能就不是这么一回事了!
2020/03/04 日漫
php 模拟POST|GET操作实现代码
2010/07/20 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
Thinkphp5框架简单实现钩子(Hook)行为的方法示例
2019/09/03 PHP
jQuery-ui中自动完成实现方法
2010/06/10 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
js如何判断用户是在PC端和还是移动端访问
2014/04/24 Javascript
javascript 获取函数形参个数
2014/07/31 Javascript
jQuery内部原理和实现方式浅析
2015/02/03 Javascript
js实现内容显示并使用json传输数据
2016/03/16 Javascript
javascript实现简易计算器
2017/02/01 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
基于BootStrap的前端分页带省略号和上下页效果
2017/05/18 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
基于vue.js的分页插件详解
2017/11/27 Javascript
vue实现选项卡及选项卡切换效果
2018/04/24 Javascript
vue-router中scrollBehavior的巧妙用法
2018/07/09 Javascript
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
JS中的算法与数据结构之列表(List)实例详解
2019/08/16 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
JS实现音量控制拖动
2020/01/15 Javascript
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
简单谈谈Python中的元祖(Tuple)和字典(Dict)
2017/04/21 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
python 接口实现 供第三方调用的例子
2019/08/13 Python
发现世界上最好的珠宝设计师:JewelStreet
2017/12/17 全球购物
澳大利亚设计的优质鞋类和适合澳大利亚生活方式的服装:Rivers
2019/04/23 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
外贸英语专业求职信范文
2013/12/25 职场文书
伦敦奥运会口号
2014/06/13 职场文书
服装设计专业求职信
2014/06/16 职场文书
大专生自荐书范文
2014/06/22 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
Python如何解决secure_filename对中文不支持问题
2021/07/16 Python