Python实现生命游戏
1. 生命游戏是什么
生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞。一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;相反,如果周围活细胞过少,这个细胞会因太孤单而死去。
规则看起来很简单,但却能演绎出无穷无尽的内容。

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

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

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

更复杂的图案。
来体会一下这些作品的脑洞以及震撼:
史诗般的生命游戏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退出。
单纯的看这段程序,好像并没有什么问题,代码逻辑正确、清晰。
效果图:

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,OpenGL生命游戏
初学Python和OpenGL,练手的第一个小程序life.py,这个小程序在日后会不断调整,增加类.优化判断及操作 执行效果: 按正规生命游戏的规则: 1.周围生命等于3时产生生命 2.周围生命等于 ...
- python实现简单动画——生命游戏
生命游戏 生命游戏的宇宙是一个无限的,其中细胞的二维正交网格,每个细胞处于两种可能的状态之一,即*活着*或*死亡*(分别是*人口稠密*和*无人居住*).每个细胞与它的八个邻居相互作用,这八个邻居是水平 ...
- Python 速通爆肝、列表推导式、生成器、装饰器、生命游戏
列表推导式.赋值.切片(替换.插入).字符串处理与判断.enumerate().格式化字符串.读写文件.global 关键字.字符串startswith().类与对象.生成器.装饰器.Self.*ar ...
- 生命游戏(python实现,pygame显示图形)
# 游戏规则:# 生命游戏(Game of Life),或者叫它的全称John Conway's Game of Life.是英国数学家约翰·康威在1970年代所发明的一种元胞自动机.# 1. 活细胞 ...
- 12岁的少年教你用Python做小游戏
首页 资讯 文章 频道 资源 小组 相亲 登录 注册 首页 最新文章 经典回顾 开发 设计 IT技术 职场 业界 极客 创业 访谈 在国外 - 导航条 - 首页 最新文章 经典回顾 开发 ...
- Conway生命游戏
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/9986679.html 作者:窗户 Q ...
- [LeetCode] Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- React项目(二):生命游戏
引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...
- 生命游戏/Game of Life的Java实现(转)
首先简单介绍一下<生命游戏> 生命游戏其实是一个零玩家游戏.它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死 ...
随机推荐
- Mybatis 插入后返回数据库自动增长ID
MySQL和MSSQL返回主键方法 在personMap.xml中 <insert id="addPerson" parameterType="orm.Person ...
- Sphinx-实战
配置完成后, 有了数据源.索引文件存储位置等, 便可以使用 indexer 工具创建索引, 收集要被检索的数据 -c 指定配置文件 默认使用 etc/sphinx.conf --all 对所有索引重新 ...
- 物联网通信协议——比较-MQTT、 DDS、 AMQP、XMPP、 JMS、 REST、 CoAP
物联网通信协议——比较-MQTT. DDS. AMQP.XMPP. JMS. REST. CoAP AMQP & MQTT & DDS (https://www.youtube.c ...
- LNMP架构二
Nginx默认虚拟主机 1.首先修改nginx.conf文件,删除server及下面的,在http最后添加include vhost/*.conf; (指定虚拟主机目录,并读取以.conf结尾的文件) ...
- C语言之文件操作08——总结
C程序的文件操作共涵盖7个例题,包括格式打印,文件读取,条件查找,矩阵的文件操作,数据格式输入及调用计算等内容. 文件操作使得程序有更强的拓展性,使其能够单独保存数据.这为程序的调试和优化打下了坚实的 ...
- jfinal的maven配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- [MySQL] Innodb參数优化
innodb_buffer_pool_size innodb_buffer_pool_size 參数用来设置Innodb 最基本的Buffer(Innodb_Buffer_Pool)的大小,也就是缓存 ...
- atitit.企业管理----商业间谍策略的使用与防务
atitit.企业管理----商业间谍策略的使用与防务 1. 间谍的历史 2 1.1. 公元前10世纪,<旧约全书>中的<士师记>里讲述了参孙的故事是最早的间谍故事. 2 1. ...
- Atitit.js获取上传文件全路径
Atitit.js获取上传文件全路径 1. 默认的value只能获取文件名..安全原因.. 1 2. Firefox浏览器的读取 1 3. Html5 的file api 2 4. 解决方法::使用a ...
- C#新特性, dynamic, ExpandObject
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx using System; using System ...