从零开始学Python(6) -----在游戏中学习Python编程-编写”生命游戏”

上一次,我们尝试了用Tkinter的GUI库来编写简单的游戏。今天我们进一步编写一个稍微复杂的游戏吧。我们今天要编写的是一个叫“生命游戏”的模拟游戏。这个游戏虽然简单,但是看起来很有趣,大家可以尝试一下。

什么是生命游戏?

这是一款模拟英国生物群体兴衰的环境游戏,由英国数学家约翰·霍顿·康威(John Horton Conway)设计。

详细介绍请看百度百科生命游戏

实际的运行效果如下:

如上图所示,在生命游戏中,生物(细胞)的生与死用二维矩形表示。红色圆圈是活细胞。并且有一个基本规则,即生物群体不得居住在人口稀少或人满为患的区域。

下一代生物的生死是通过检查生物的周围环境(8个方向)的活细胞个数来确定的。换句话说,生物的诞生和淘汰通过以下的简单规则来确定。

生活游戏规则如下:

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

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

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

开始编写游戏

那么接下来就让我们开始编写游戏吧。下面的程序中,当游戏启动时,我们随机生成初始化界面,然后根据圣明游戏的规则每300ms执行一次游戏。

from random import randint
from tkinter import *

# 变量・常量定义 --- (*1)
COLS, ROWS = [30, 20] # 定义舞台的大小
CW = 20 # 单元格的大小
data = [] # 保存舞台数据
for y in range(0, ROWS): # 随机初始化舞台
    data.append([(randint(0, 9) == 0) for x in range(0, COLS)])

# 定义生命游戏的规则 --- (*2)
def check(x, y):
    # 计算周围活细胞的数量
    cnt = 0
    tbl = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]
    for t in tbl:
        xx, yy = [x + t[0], y + t[1]]
        if 0 <= xx < COLS and 0 <= yy < ROWS:
            if data[yy][xx]: cnt += 1
    # 更具规则决定细胞的死活
    if cnt == 3: return True # 诞生新细胞
    if data[y][x]:
        if 2 <= cnt <= 3: return True # 继续存活
        return False # 细胞太少 or 细胞太多
    return data[y][x]

 # 下一代细胞数据的生成 --- (*3)
def next_turn():
    global data
    data2 = []
    for y in range(0, ROWS):
        data2.append([check(x, y) for x in range(0, COLS)])
    data = data2 # 报数据替换成下一代细胞的数据

# 游戏界面 --- (*4)
win = Tk() # 生成主窗口
cv = Canvas(win, width = 600, height = 400) # キャンバスを作成
cv.pack()

# 绘制舞台 --- (*5)
def draw_stage():
    cv.delete('all') # 清除原有界面内容
    for y in range(0, ROWS):
        for x in range(0, COLS):
            if not data[y][x]: continue
            x1, y1 = [x * CW, y * CW]
            cv.create_oval(x1, y1, x1 + CW, y1 + CW,
                fill="red", width=0) # 绘制活细胞

# 每隔300m重新绘制画面 --- (*6)
def game_loop():
    next_turn() # 产生下一代细胞数据
    draw_stage() # 绘制舞台
    win.after(300, game_loop) # 指定重新绘制的时间

game_loop() # 循环执行游戏
win.mainloop() # 进入消息循环

将上述代码另存为“ lifegame-simple.py”。然后,命令行执行以下命令。

 # Windows
 python lifegame-simple.py

当运行程序,就能得到文章开头介绍的画面。

接下来就让我们看看具体的代码吧!

首先,在代码的开头(* 1),定义了变量和常量。其中,变量用于管理二维矩形舞台上细胞的生死状态。每一个单元格的初始状态是随机确定的。True代表活,False代表死亡。

在代码的(* 2)和(* 3)部分中,根据游戏规则确定下一代单元格的状态。(* 2)中的check()函数返回指定位置(x,y)的下一代细胞的生死状态。生死状态取决于该位置(8个方向)周围的活细胞数量。在这里,指定位置的8个方向的相对坐标保存在变量tbl中。然后,使用for.. in ..语法来循环计算每个单元格的生死状态。在(* 3)部分中,同样用check()函数来确认舞台上所有单元格的生死状态。

在代码的(* 4)部分中,创建一个窗口,并在其上放置可以绘制图形的画布(具体内容上一次已经介绍过了)。

在代码的(* 5)部分中,首先清除了所有现有图形内容,然后再重新绘制单元格。这里,使用create_oval()方法来绘制红色圆圈来代表每一个活细胞。

最后,在(* 6)部分中,每隔300毫米重新绘制游戏界面。after()函数的用法如下:

 [语法格式] msec毫秒后、执行func函数

 win.after(msec, func)

总结

今天,我们介绍了如何制作生命游戏。和之前的文章内容比较起来,可能稍微复杂了一点。

不过,总共的代码行数也不超过60行,所以,大家一边看代码说明,一边自己尝试编写,应该很快就能掌握。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值