python康威生命游戏的图形化界面实现

康威生命游戏(Conway’s Game of Life)是由英国数学家约翰·何顿·康威(John Horton Conway)在1970年发明的一款零玩家的细胞自动机模拟游戏。尽管它的名字中有“游戏”,但实际上它并不需要玩家参与操作,而是通过初始条件下的设定让程序自动演化出各种复杂的图案和行为。

游戏规则

康威生命游戏在一个二维网格上进行,每个格子有两种状态:存活(通常用黑色表示)或死亡(通常用白色表示)。游戏的演变遵循以下三条简单的规则:

  1. 繁殖:如果一个死亡的细胞周围恰好有三个存活的邻居,那么这个细胞就会变成存活状态。
  2. 生存:如果一个存活的细胞周围有两个或三个存活的邻居,那么这个细胞继续保持存活状态。
  3. 死亡:所有其他情况下的存活细胞都会死亡;而所有其他情况下的死亡细胞都不会复活。

进化过程

游戏从一个初始配置开始,然后根据上述规则逐代进化。这些规则非常简单,但结果却异常复杂多变。一些初始模式会形成稳定不变的结构(如静止点、振荡器),还有一些模式会产生移动的对象(如滑翔机),甚至可以构建逻辑门和其他计算元件,理论上可以模拟任何计算机程序的行为。

用途与影响

康威生命游戏不仅是一种娱乐方式,还在以下几个方面产生了重要影响:

  • 计算机科学:展示了如何使用简单的规则产生复杂的系统,启发了研究复杂系统的科学家。
  • 生物学:帮助理解生物体自我复制和进化的机制。
  • 艺术与设计:许多艺术家利用其产生的图案进行创作。

示例

以下是一些著名的康威生命游戏中出现的图案示例:

  • 静止点(Still Life):这种模式在一代到下一代之间保持不变。例如,块(Block)、蜂窝(Beehive)等。
  • 振荡器(Oscillator):这种模式会在固定数量的世代后回到原始状态。例如,闪烁灯(Blinker)、托盘(Toad)等。
  • 滑翔机(Glider):一种能够无限期地移动而不改变形状的模式。
  • R-Pentomino:一种由五个单元组成的初始模式,它可以演化成一系列复杂的动态结构。

康威生命游戏以其简单规则产生复杂行为的能力,成为了探索复杂系统的一个经典案例。

这段代码实现了一个图形化的康威生命游戏(Conway’s Game of Life)。它使用了Python的tkinter库来创建图形用户界面(GUI),并通过简单的规则模拟细胞自动机的行为。以下是代码的详细注释:

import tkinter as tk  # 导入tkinter库,用于创建图形用户界面
import random         # 导入random库,用于随机初始化细胞状态class GameOfLife:def __init__(self, master, width=40, height=20, cell_size=20):"""初始化GameOfLife类的实例。:param master: 主窗口对象:param width: 网格的宽度(列数):param height: 网格的高度(行数):param cell_size: 每个单元格的大小(像素)"""self.master = master          # 设置主窗口对象self.width = width            # 设置网格的宽度self.height = height          # 设置网格的高度self.cell_size = cell_size    # 设置每个单元格的大小self.grid = [[0 for _ in range(width)] for _ in range(height)]  # 初始化网格,所有单元格初始为死亡状态(0)self.canvas = tk.Canvas(master, width=width * cell_size, height=height * cell_size)  # 创建画布对象self.canvas.pack()            # 将画布添加到主窗口中self.initialize_cells()       # 随机初始化细胞状态self.draw_grid()              # 绘制初始网格self.running = False          # 初始状态下游戏不运行self.start_button = tk.Button(master, text="Start", command=self.toggle_running)  # 创建“Start”按钮self.start_button.pack(side=tk.LEFT)  # 将“Start”按钮添加到主窗口左侧self.reset_button = tk.Button(master, text="Reset", command=self.reset_grid)  # 创建“Reset”按钮self.reset_button.pack(side=tk.RIGHT)  # 将“Reset”按钮添加到主窗口右侧def initialize_cells(self):"""随机初始化网格中的细胞状态。"""for i in range(self.height):for j in range(self.width):self.grid[i][j] = random.choice([0, 1])  # 随机选择每个单元格的状态(存活或死亡)def draw_grid(self):"""在画布上绘制当前网格的状态。"""self.canvas.delete("all")  # 清除画布上的所有内容for i in range(self.height):for j in range(self.width):color = "black" if self.grid[i][j] else "white"  # 根据单元格状态设置颜色x1 = j * self.cell_size  # 计算单元格左上角x坐标y1 = i * self.cell_size  # 计算单元格左上角y坐标x2 = x1 + self.cell_size  # 计算单元格右下角x坐标y2 = y1 + self.cell_size  # 计算单元格右下角y坐标self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="gray")  # 绘制单元格矩形def get_neighbors_count(self, x, y):"""计算指定单元格周围的存活邻居数量。:param x: 单元格的行索引:param y: 单元格的列索引:return: 周围存活邻居的数量"""count = 0for i in range(max(0, x-1), min(x+2, self.height)):for j in range(max(0, y-1), min(y+2, self.width)):if (i != x or j != y) and self.grid[i][j]:  # 忽略自身单元格count += 1return countdef next_generation(self):"""根据康威生命游戏规则计算下一代的网格状态。"""new_grid = [[0 for _ in range(self.width)] for _ in range(self.height)]  # 初始化新的网格for i in range(self.height):for j in range(self.width):neighbors = self.get_neighbors_count(i, j)  # 获取当前单元格周围的存活邻居数量if self.grid[i][j] == 1 and neighbors in [2, 3]:  # 生存条件new_grid[i][j] = 1elif self.grid[i][j] == 0 and neighbors == 3:  # 繁殖条件new_grid[i][j] = 1self.grid = new_grid  # 更新网格状态self.draw_grid()      # 绘制更新后的网格def update(self):"""定时更新网格状态,每100毫秒调用一次next_generation方法。"""if self.running:self.next_generation()  # 如果游戏正在运行,则计算下一代self.master.after(100, self.update)  # 每100毫秒再次调用update方法def toggle_running(self):"""切换游戏的运行状态,并更新按钮文本。"""self.running = not self.running  # 切换运行状态if self.running:self.start_button.config(text="Stop")  # 如果游戏正在运行,则将按钮文本改为“Stop”else:self.start_button.config(text="Start")  # 如果游戏暂停,则将按钮文本改为“Start”def reset_grid(self):"""重置网格状态并停止游戏。"""self.grid = [[0 for _ in range(self.width)] for _ in range(self.height)]  # 初始化网格,所有单元格初始为死亡状态self.draw_grid()      # 绘制重置后的网格self.running = False  # 停止游戏self.start_button.config(text="Start")  # 将按钮文本改为“Start”if __name__ == "__main__":root = tk.Tk()  # 创建主窗口对象root.title("Conway's Game of Life")  # 设置窗口标题game = GameOfLife(root)  # 创建GameOfLife实例game.update()  # 启动定时更新机制root.mainloop()  # 进入主事件循环,等待用户操作

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

功能总结

  1. 初始化:创建一个随机填充的网格。
  2. 绘制网格:在画布上绘制当前网格的状态。
  3. 计算下一代:根据康威生命游戏的规则计算下一代的网格状态。
  4. 控制按钮
    • Start/Stop:启动或停止游戏的演化。
    • Reset:重置网格状态。
  5. 定时更新:每隔100毫秒更新一次网格状态。

技术要点

  • tkinter:用于创建图形用户界面(GUI)。
  • Canvas:用于绘制网格和单元格。
  • Button:用于控制游戏的开始、停止和重置。
  • Event Loop:通过root.mainloop()进入主事件循环,处理用户输入和定时任务。

这个代码提供了一个简单而有效的康威生命游戏的图形化实现,适合初学者学习如何使用tkinter库进行基本的GUI编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】链表应用-链表重新排序

重新排序 反转链表预期实现思路解题过程code力扣代码核心代码完整代码 总结 删除链表中间节点代码解惑 链表重新排序题目描述解题思路解题过程复杂度代码力扣代码完整代码 反转链表 预期实现 思路 你选用何种方法解题? 我选用了迭代法来反转链表。这是一种经典且高…

pytest-xdist 进行多进程并发测试!

在软件开发过程中,测试是确保代码质量和可靠性的关键步骤。随着项目规模的扩大和复杂性的增加,测试用例的执行效率变得尤为重要。为了加速测试过程,特别是对于一些可以并行执行的测试用 例,pytest-xdist 提供了一种强大的工具&…

mysql8安装时提示-缺少Microsoft Visual C++ 2019 x64 redistributable

MySQL8.0安装包mysql-8.0.1-winx64进行安装,提示:This application requires Visual Studio 2019 x64Redistributable, Please install the Redistributable then runthis installer again。出现这个错误是因为我们电脑缺少Microsoft Visual C 这个程序&…

【MySQL】深度理解事务的隔离性:全面讲解事务的四种隔离级别

**前言:**上节内容我们主要说了如果没有设置保存点, 也可以回滚,但是只能回滚到事务的开始。直接使用rollback的前提是事务还没有提交。并且如果一个事务被提交了,就不可以回退。同时我们也可以使用savepoint设置回滚点。 可以自己…

项目实战 —— HTTP服务器设计与实现

目录 一,项目介绍 二,背景知识补充 2.1 http特点 2.2 URI,URL,URN 2.3 http请求方法 三,前置功能实现 3.1 日志编写 3.2 封装相关套接字 3.3 http请求结构设计 3.4 http响应结构设计 3.5 http服务器主体逻辑…

GitHub Copilot:智能助手觉醒

GitHub Copilot: The agent awakens - The GitHub Blog github copilot 官方文档刚刚宣布支持 agent 模式! 这一模式和之前的 chat 方式不同,类似于 cursor 可以根据需求直接运行、调试和修改代码 这一模式在 preview 版本可以使用,并且需…

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗,每一次入侵背后都有一个实体(个人或组织)”。这一经典观点概括了网络攻防的深层本质。无论是APT(高级持续性威胁)攻击、零日漏洞利用,还是简单的钓鱼攻击&am…

深入浅出谈VR(虚拟现实、VR镜头)

1、VR是什么鬼? 近两年VR这次词火遍网上网下,到底什么是VR?VR是“Virtual Reality”,中文名字是虚拟现实,是指采用计算机技术为核心的现代高科技手段生成一种虚拟环境,用户借助特殊的输入/输出设备&#x…

postman免登录版本,实测可用(解决一直卡在登录界面无法进入的问题)

一、背景 2025今年开工后,打开postman,一直提示需要登录,但是一直卡在登录界面,好几个人的postman都是这样的情况,不知道是什么原因。 折腾几小时无果,网上下载了各种版本都试了,最新的版本也…

Unity中Spine骨骼动画完全指南:从API详解到避坑实战

Unity中Spine骨骼动画完全指南:从API详解到避坑实战 一、为什么要选择Spine? Spine作为专业的2D骨骼动画工具,相比传统帧动画可节省90%资源量。在Unity中的典型应用场景包括: 角色换装系统(通过插槽替换部件&#xf…

HTTP异步Client源码解析

我们知道Netty作为高性能通信框架,优点在于内部封装了管道的连接通信等操作,用户只需要调用封装好的接口,便可以很便捷的进行高并发通信。类似,在Http请求时,我们通过调用HttpClient,内部使用java NIO技术&…

Golang:Go 1.23 版本新特性介绍

流行的编程语言Go已经发布了1.23版本,带来了许多改进、优化和新特性。在Go 1.22发布六个月后,这次更新增强了工具链、运行时和库,同时保持了向后兼容性。 Go 1.23 的新增特性主要包括语言特性、工具链改进、标准库更新等方面,以下…

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…

SQL Server 数据库迁移到 MySQL 的完整指南

文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…

RabbitMQ深度探索:死信队列

死信队列产生背景: RabbitMQ 死信队列俗称 备胎队列:消息中间件因为某种原因拒收该消息后,可以转移到私信队列中存放,死信队列也可以有交换机和路由 key 等 生产死信队列的原因: 消息投递到 MQ 存放,消息已…

蓝桥算法基础2

位运算 按位与,x&1x%2.因为1不论和几位二进制与,都只有最后一位为1,前面都是0,那么&前面也都为0,只有最后一位,若为1那么2的0次方为1,该数一定为奇数,与取余结果同&#xff…

B站自研的第二代视频连麦系统(上)

导读 本系列文章将从客户端、服务器以及音视频编码优化三个层面,介绍如何基于WebRTC构建视频连麦系统。希望通过这一系列的讲解,帮助开发者更全面地了解 WebRTC 的核心技术与实践应用。 背景 在文章《B站在实时音视频技术领域的探索与实践》中&#xff…

redis之AOF持久化过程

流程图 在redis.conf文件中配置appendonly为yes则开启aof持久化机制 #开启aof持久化,默认关闭为no appendonly no也可以在命令行开启 aof刷盘策略 #每个写操作都会同步刷盘。 appendfsync always #执行命令后先放入aof缓冲区,每秒钟将缓冲区数据刷盘…

力扣.623. 在二叉树中增加一行(链式结构的插入操作)

Problem: 623. 在二叉树中增加一行 文章目录 题目描述思路复杂度Code 题目描述 思路 1.首先要说明,对于数据结构无非两大类结构:顺序结构、链式结构,而二叉树实质上就可以等效看作为一个二叉链表,而对于链表插入一个节点的操作是应…

【GoLang】切片的面试知识点

nil切片 和 空切片 nil切片是只声明但未初始化,没有分配底层数组的内存空间, 空切片是初始化了的,有分配数组内存,只是数组内没有元素。 二者都可以正常扩容、遍历。不会报错。 append 如何添加切片 append 可以增加切片&…