我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python 生命游戏(tkinter版)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python 生命游戏(tkinter版)

生命游戏(Game of Life)

由剑桥大学约翰·何顿·康威设计的计算机程序。美国趣味数学大师马丁·加德纳(Martin Gardner,1914-2010)通过《科学美国人》杂志,将康威的生命游戏介绍给学术界之外的广大渎者,一时吸引了各行各业一大批人的兴趣,这时细胞自动机课题才吸引了科学家的注意。

游戏概述

用一个二维表格表示“生存空间”,空间的每个方格中都可放置一个生命细胞,每个生命细胞只有两种状态:“生”或“死”。用绿色方格表示该细胞为“生”,空格(白色)表示该细胞为“死”。或者说方格网中绿色部分表示某个时候某种“生命”的分布图。生命游戏想要模拟的是:随着时间的流逝,这个分布图将如何一代一代地变化。死亡太沉重,我想称它为“湮灭”状态。

生存定律

生存空间的每个方格都存在一个细胞,它的周边紧邻的8个方格上的称为邻居细胞。
(1)当前细胞为湮灭状态时,当周围有3个存活细胞时,则迭代后该细胞变成存活状态(模拟繁殖)。
(2)当前细胞为存活状态时,当周围的邻居细胞少于2个存活时,该细胞变成湮灭状态(数量稀少)。
(3)当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成湮灭状态(数量过多)。
(4)当前细胞为存活状态时,当周围有2个或3个存活细胞时,该细胞保持原样。

简单来说,活细胞Cell看作是‘1’,死Cell看作‘0’,8个邻居的累加和Sum决定了下一轮的状态:

“繁殖”:Cell=0,若Sum=3,则Cell=1。
“稀少”:Cell=1,若Sum<2,则Cell=0。
“过多”:Cell=1,若Sum>3,则Cell=0。
“正常”:Cell=1,若Sum=2或3,则Cell=1。

生存空间中生命的繁殖和湮灭,如下图所示:

图形结构

在游戏进行中,杂乱无序的细胞会逐渐演化出各种精致、有形的图形结构;这些结构往往有很好的对称性,而且每一代都在变化形状。一些形状一经锁定就不会逐代变化。有时,一些已经成形的结构会因为一些无序细胞的“入侵”而被破坏。但是形状和秩序经常能从杂乱中产生出来。

通常会有以下四种状态:

不动点(fixed points):变化终结于恒定图像
交替态(alternation):图像出现周期性变化
随机态(randomness):图像变化近乎随机
复杂态(complexity):图像存在某种复杂规律

常见的不动结构:

周期变化的结构:

逐步趋向湮灭的结构:


由一根10个连续细胞演化出来的周期结构:


动态变化后全部湮灭的结构:


移动的飞船:周期变化且逐渐向右平移

飞船到了边界变成向对角线移动的“滑翔者”,滑翔者到了边界成为不动的方块

更多有趣的图形结构有待发现,用代码来辅助这项工作还是比较方便的.....


代码实现

用tkinter库实现了软件界面,画布、按钮、标签等控件都是配角,全是为表现生命繁殖演化的核心代码类方法 Lifes.reproduce() 作帮手的,源代码lifegame.pyw如下:

from tkinter import messagebox as msgboximport tkinter as tkimport webbrowserimport randomclass Lifes:    def __init__(self, rows=36, cols=36):        self.row = rows+2        self.col = cols+2        self.items = [[0]*self.col for _ in range(self.row)]        self.histroy = []        self.histroySize = 30        self.running = False        self.runningSpeed = 100            def rndinit(self, rate=0.1):        self.histroy = []        for i in range(self.row):            for j in range(self.col):                rnd = random.random()                if rnd > 1-rate:                    self.items[i][j]=1    def reproduce(self):        new = [[0]*self.col for _ in range(self.row)]        self.add_histroy()        if len(self.histroy) > self.histroySize:            self.histroy.pop(0)        for i in range(self.row):            for j in range(self.col):                if i*j==0 or i==self.row-1 or j==self.col-1:                    new[i][j]=0                else:                    lifes=0                    for m in range(i-1,i+2):                        for n in range(j-1,j+2):if m==i and n==j:    continuelifes += self.items[m][n]                    if self.items[i][j]:                        if lifes==2 or lifes==3:new[i][j]=1                        else:new[i][j]=0                    else:                        if lifes==3:new[i][j]=1        for idx,narray in enumerate(new):            self.items[idx] = narray    def is_stable(self):        if len(self.histroy)',on_Click)def drawLifes():    R,XY = 8,[50+i*20 for i in range(36)]    if Life.running:        for i,x in enumerate(XY):            for j,y in enumerate(XY):                if Life.items[i+1][j+1]:                    tv.itemconfig(rect[i][j],fill='green',outline='green')                else:                    tv.itemconfig(rect[i][j],fill='lightgray',outline='lightgray')        tv.update()        Life.reproduce()        if Life.is_stable():            Life.running = False            if sum(sum(Life.items,[])):                msgbox.showinfo('Message','生命繁殖与湮灭进入稳定状态!!!')            else:                msgbox.showinfo('Message','生命全部湮灭,进入死亡状态!!!')    win.after(Life.runningSpeed, drawLifes)def StartLife():    if sum(sum(Life.items,[])):        Life.histroy = []        Life.running = True    else:        msgbox.showinfo('Message','请点击小方块填入生命细胞,或者使用随机功能!')def BreakLife():    Life.running = not Life.running    if Life.running:        Life.histroy.clear()        Life.add_histroy()def RandomLife():    Life.rndinit()    Life.running = Truedef ClearLife():    Life.running = False    Life.histroy = []    Life.items = [[0]*38 for _ in range(38)]    for x in range(36):        for y in range(36):            tv.itemconfig(rect[x][y],fill='lightgray',outline='lightgray')def btnCommand(i):    if   i==0: return StartLife    elif i==1: return BreakLife    elif i==2: return RandomLife    elif i==3: return ClearLifedef on_Enter(event):    tCanvas.itemconfig(tVisit, fill='magenta')def on_Leave(event):    tCanvas.itemconfig(tVisit, fill='blue')def on_Release(event):    url = 'https://blog.csdn.net/boysoft2002?type=blog'    webbrowser.open(url, new=0, autoraise=True)def on_Click(event):    x,y = (event.x-40)//20,(event.y-40)//20    if not Life.running:        if Life.items[x+1][y+1]:            tv.itemconfig(rect[x][y],fill='lightgray',outline='lightgray')        else:            tv.itemconfig(rect[x][y],fill='red',outline='red')        Life.items[x+1][y+1] = not Life.items[x+1][y+1]def on_Close():    if msgbox.askokcancel("Quit","Do you want to quit?"):        Life.running = False        print(Copyright())        win.destroy()def Introduce():    txt = '''【生命游戏】\n\n生存定律:    (1)当前细胞为湮灭状态时,当周围有3个存活细胞时,则迭代后该细胞变成存活状态(模拟繁殖)。    (2)当前细胞为存活状态时,当周围的邻居细胞少于2个存活时,该细胞变成湮灭状态(数量稀少)。    (3)当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成湮灭状态(数量过多)。    (4)当前细胞为存活状态时,当周围有2个或3个存活细胞时,该细胞保持原样。'''    return txtdef Copyright():    return 'Lifes Game Ver1.0\nWritten by HannYang, 2022/08/01.'if __name__ == '__main__':    win = tk.Tk()    X,Y = win.maxsize()    W,H = 1024,800    winPos = f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}'    win.geometry(winPos)    win.resizable(False, False)    win.title('生命游戏 Ver1.0')    win.update()    drawCanvas()    Life = Lifes()    drawLifes()    tLabel = tk.Label(win, width=30, height=20, background='lightgray')    tLabel.place(x=780, y=38)    tLabel.config(text='\n\n\n'.join((Introduce(),Copyright())))    tLabel.config(justify=tk.LEFT,anchor="nw",borderwidth=10,wraplength=210)    tButton = [None]*4    bX,bY,dY = 835, 458, 50    txt = ['开始','暂停','随机','清空']    for i in range(4):        tButton[i] = tk.Button(win, text=txt[i], command=btnCommand(i))        tButton[i].place(x=bX, y=bY+dY*i, width=120, height=40)         tCanvas = tk.Canvas(win, width=200, height=45)    tCanvas.place(x=800,y=716)    tVisit = tCanvas.create_text((88, 22), text=u"点此访问Hann's CSDN主页!")    tCanvas.itemconfig(tVisit, fill='blue', tags=('btnText'))    tCanvas.tag_bind('btnText','',on_Enter)    tCanvas.tag_bind('btnText','',on_Leave)    tCanvas.tag_bind('btnText','',on_Release)    win.protocol("WM_DELETE_WINDOW", on_Close)    win.mainloop()

编译命令

D:\> pyinstaller -F lifegame.pyw --noconsole

运行界面

使用简介

在生存空间里点击方格种植细胞(甚至可以画出你要表达的图形),然后点击开始;点下暂停键,则可以任意编辑生命图形,再点开始继续运行;点随机键则由软件随机生成细胞位置;清空键可以在任何时候清空生存空间,进入暂停编辑状态。 

后续改进

Lifes类预留了histroy属性,后续可以增加回退功能;代码缺点是生存空间的行列被我写死了,以后版本中可以改进成任意定义行列数;另一个缺点是对稳定状态的判断比较简单,之后可以增加计算变化周期的功能。

优点就是可以任意编辑你的图形,最后以一张自己的网名画的图作收尾:


前部分介绍性文字来源于百度百科等网络资源 

来源地址:https://blog.csdn.net/boysoft2002/article/details/126131069

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python 生命游戏(tkinter版)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python用tkinter开发的扫雷游戏

目录2.实现代码3.另一种精致一点的实现1.实现效果2.实现代码# 导入所需库 from tkinter import * import randomclass main:# 定义一个类,继承 tkinter 的 Button# 用来保存按
2022-06-02

JavaScript实现生命游戏的方法

这篇文章主要介绍JavaScript实现生命游戏的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!javascript是一种什么语言javascript是一种动态类型、弱类型的语言,基于对象和事件驱动并具有相对安全
2023-06-14

怎么在python中使用tkinter制作一个2048游戏

怎么在python中使用tkinter制作一个2048游戏?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。创建main.py代码:from tkinter import *fro
2023-06-14

怎么用Python+Tkinter实现经典井字棋小游戏

这篇文章主要讲解了“怎么用Python+Tkinter实现经典井字棋小游戏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Python+Tkinter实现经典井字棋小游戏”吧!演示介绍首
2023-06-29

怎么在python中使用tkinter实现一个扫雷游戏

怎么在python中使用tkinter实现一个扫雷游戏?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现代码# 导入所需库from tkinter import
2023-06-15

学习python:实例3.终端版拼图游戏

效果:输入数字进行移动,当数字排列成为【1,2,3,4,5,6,7,8】游戏胜利!代码:# 拼图from sys import exitfrom os import systemfrom random import shuffle# 游戏胜
2023-01-31

Python外星人入侵游戏编程完整版

PYTHON游戏编程外星人入侵的完整实现思路,具体内容如下 准备工作:下载python,比如Anaconda3(64 bit),导入pygame游戏包1.外星人设置,alien.py,代码:import pygame from pygame
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录