python GUI编程实现扫雷游戏
作者:ZJF010101 发布时间:2023-10-27 20:41:29
标签:python,GUI,扫雷
前言
1992年扫雷被加入到windows3.1,成为早期windows的经典游戏。近来接触python的GUI(图形化)编程,于是通过编写扫雷来实践学习。有关程序的问题和想法欢迎大家指出。
一、基本思路
(1)程序的核心数据是二维列表control_list[16][16],值-1代表雷,0和其他数字代表四周雷的数目。函数randomization()随机40个雷的 位置
(2)生成16x16个按钮控件,根据control_list列表确定点击相应的按钮时执行的代码。如按照游戏规则:点击对应control_list列表值为0的按钮时,递归执行函数re()来扫雷,当点击对应的control_list列表值为-1时直接结束游戏,对应大于0的值则只需隐藏当前的按钮控件。
其他:本程序用到的GUI编程库为tkinter, 控件的布局统一采用place()方法
二、源代码
1.运行效果
运行效果如下(示例):
2.上源码
"""
Created on Tuesday, April 5,2022
@author:I
"""
from tkinter import *
from tkinter import messagebox
import random
#定义五个二维数组,充当整个程序的数据
control_list=[[0 for i in range(16)] for j in range(16)]#二维列表,呈现雷和数字的分布。
show_list=[[0 for i in range(16)] for j in range(16)]#二维列表,控制遮住或显示雷和数字。(0--遮住,1--显示)
button_list=[[0 for i in range(16)] for j in range(16)]#二维的按钮列表(显示在上层)
label_list=[[0 for i in range(16)] for j in range(16)]#二维的标签列表(显示在下层)
mark_list=[[0 for i in range(16)] for j in range(16)]#二维标记列表
num_mine=40#控制游戏结束
counter=0#计时
T ,t= 1,0#游戏结束的判断
def randomization(c_list):#随机初始化雷的分布即初始化列表control_list
? ? num=0
? ? while num<40:
? ? ? ? x=random.randint(0,15)
? ? ? ? y=random.randint(0,15)
? ? ? ? if(c_list[x][y]==0):
? ? ? ? ? ? num+=1
? ? ? ? ? ? c_list[x][y]=-1
? ? for i in range(16):
? ? ? ? for j in range(16):
? ? ? ? ? ? if(c_list[i][j]>-1):
? ? ? ? ? ? ? ? if (i>0 and c_list[i-1][j]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (i<15 and c_list[i+1][j]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (j>0 and c_list[i][j-1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (j<15 and c_list[i][j+1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (i>0 and j>0 and c_list[i-1][j-1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (i<15 and j<15 and c_list[i+1][j+1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (i>0 and j<15 and c_list[i-1][j+1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
? ? ? ? ? ? ? ? if (i<15 and j>0 and c_list[i+1][j-1]==-1):
? ? ? ? ? ? ? ? ? ? c_list[i][j]+=1
def game_core():
? ? randomization(control_list)
? ? for row in range(16):
? ? ? ? for col in range(16):
? ? ? ? ? ? if(control_list[row][col]==-1):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="?",font=('arial', 15, 'bold'),fg="black",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==0):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==1):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="1",font=('arial', 15, 'bold'),fg="red",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==2):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="2",font=('arial', 15, 'bold'),fg="blue",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==3):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="3",font=('arial', 15, 'bold'),fg="green",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==4):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="4",font=('arial', 15, 'bold'),fg="white",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==5):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="5",font=('arial', 15, 'bold'),fg="red",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==6):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="6",font=('arial', 15, 'bold'),fg="blue",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==7):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="7",font=('arial', 15, 'bold'),fg="green",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? ? ? ? ? elif(control_list[row][col]==8):
? ? ? ? ? ? ? ? label_list[row][col]=Label(root,text="8",font=('arial', 15, 'bold'),fg="white",bg="#AAAAAA",relief=RIDGE)
? ? ? ? ? ? ? ? label_list[row][col].place(x=17+col*20,y=46+row*20,height=20,width=20)
? ? for r in range(16):
? ? ? ? for c in range(16):
? ? ? ? ? ? s = str((r)*16+c)
? ? ? ? ? ? button_list[r][c]=Button(root,text=s,activeforeground="#AAAAAA",bg="#AAAAAA",fg="#AAAAAA")
? ? ? ? ? ? button_list[r][c].place(x=17+c*20,y=46+r*20,height=20,width=20)
? ? ? ? ? ? button_list[r][c].bind("<Button-1>",button_control_l)#鼠标左击绑定函数
? ? ? ? ? ? button_list[r][c].bind("<Button-3>",button_control_r)
def button_control_l(event):#扫雷控制函数.(开始函数直接用参数r和c,但是会产生问题)
? ? r = int(event.widget["text"])//16
? ? c = int(event.widget["text"])%16
? ? global t
? ? global T
? ? if(control_list[r][c]>=1):
? ? ? ? button_list[r][c].place_forget()
? ? ? ? show_list[r][c]=1
? ? ? ? t+=1
? ? elif(control_list[r][c]==0):
? ? ? ? rec(r,c)
? ? elif(control_list[r][c]==-1 and T):
? ? ? ? button_list[r][c].place_forget()
? ? ? ? show_list[r][c]=1
? ? ? ? T=0
? ? ? ? for i in range(16):
? ? ? ? ? ? for j in range(16):
? ? ? ? ? ? ? ? if(control_list[i][j]==-1):
? ? ? ? ? ? ? ? ? ? button_list[i][j].place_forget()
? ? ? ? ? ? ? ? ? ? show_list[r][c]=1
? ? ? ? button_restart["text"]="?"
? ? ? ? messagebox.showwarning("失败","你已经被炸死了!")
? ? if t==216:
? ? ? ? ? ? T=0
? ? ? ? ? ? messagebox.showwarning("成功","恭喜你扫雷完成!")
def button_control_r(event):
? ? r = int(event.widget["text"])//16
? ? c = int(event.widget["text"])%16
? ? mark_list[r][c]=Button(root,text="?",font=('楷体', 14),activeforeground="#AAAAAA",bg="#AAAAAA",fg="yellow")
? ? mark_list[r][c].place(x=17+c*20,y=46+r*20,height=20,width=20)
? ? mark_list[r][c].bind("<Button-3>",button_control_r_change)
def button_control_r_change(event):
? ? global num_mine
? ? if (event.widget["text"]=="?" and num_mine>0):
? ? ? ? num_mine-=1
? ? ? ? event.widget["text"]="▲"
? ? ? ? cout_label["text"]=str(num_mine)
? ? elif(event.widget["text"]=="▲"):
? ? ? ? num_mine+=1
? ? ? ? cout_label["text"]=str(num_mine)
? ? ? ? event.widget.place_forget()
? ? elif (event.widget["text"]=="?" and num_mine==0):
? ? ? ? event.widget.place_forget()
def rec(r,c):#递归探测
? ? global t
? ? if control_list[r][c]>0 and show_list[r][c]==0:
? ? ? ? button_list[r][c].place_forget()
? ? ? ? show_list[r][c]=1
? ? ? ? t+=1
? ? ? ? return 0
? ? elif control_list[r][c] ==0 and show_list[r][c]==0:
? ? ? ? button_list[r][c].place_forget()
? ? ? ? show_list[r][c]=1
? ? ? ? t+=1
? ? ? ? if r>0 and c>0:
? ? ? ? ? ? rec(r-1,c-1)
? ? ? ? if r>0:
? ? ? ? ? ? rec(r-1,c)
? ? ? ? if r>0 and c<15:
? ? ? ? ? ? rec(r-1,c+1)
? ? ? ? if c<15:
? ? ? ? ? ? rec(r,c+1)
? ? ? ? if r<15 and c<15:
? ? ? ? ? ? rec(r+1,c+1)
? ? ? ? if r<15:
? ? ? ? ? ? rec(r+1,c)
? ? ? ? if r<15 and c>0:
? ? ? ? ? ? rec(r+1,c-1)
? ? ? ? if c>0:
? ? ? ? ? ? rec(r,c-1)
def time_counter(la): ?# la是标签,计时函数
? ? def counting():
? ? ? ? global counter
? ? ? ? if T:
? ? ? ? ? ? counter += 1
? ? ? ? la["text"]=str(counter)
? ? ? ? la.after(1000,counting) ?# 在1000毫秒后执行counting()函数,即循环执行counting
? ? counting()
def restart():#重新开始函数
? ? button_restart["text"]="?"
? ? cout_label["text"]="40"
? ? #数据重置
? ? for i in range(16):
? ? ? ? for j in range(16):
? ? ? ? ? ? control_list[i][j]=0
? ? ? ? ? ? show_list[i][j]=0
? ? ? ? ? ? button_list[i][j].place_forget()
? ? ? ? ? ? button_list[i][j]=0
? ? ? ? ? ? label_list[i][j].place_forget()
? ? ? ? ? ? label_list[i][j]=0
? ? ? ? ? ? if (mark_list[i][j]!=0):
? ? ? ? ? ? ? ? mark_list[i][j].place_forget()
? ? ? ? ? ? mark_list[i][j]=0
? ? global num_mine
? ? global counter
? ? global T ,t
? ? num_mine=40
? ? counter=0
? ? T ,t= 1,0
? ? game_core()
if __name__ =="__main__":
? ??
? ? root = Tk()#根窗体
? ? root.title("扫雷小游戏")
? ? root.geometry("360x410")#根窗体大小
? ? cv1 = Canvas(root,bd=15,bg="#FFFFFF",relief=RIDGE,cursor="cross",width=321,height=350)
? ? cv1.create_line(15,45,337,45)
? ? cv1.place(x=0,y=0)
? ? w=Label(root,text="你所作的选择,决定你的命运!",font=("楷体",12))
? ? w.place(x=60,y=385)
? ? button_restart=Button(root,text="?",font=('楷体', 15),bg="#AAAAAA",fg="yellow",command=restart)
? ? button_restart.place(x=150,y=17,height=27,width=27)
? ? time_label = Label(root,bg="black",fg="red",text=str(counter),font=("LcdD",15))#计时标签
? ? time_label.place(x=285,y=17,height=27,width=50)
? ? cout_label = Label(root,bg="black",fg="red",text="40",font=("LcdD",20))#计数标签
? ? cout_label.place(x=18,y=17,height=27,width=27)
? ? game_core()
? ? time_counter(time_label)
? ? root.mainloop()#监控组件,组件发生变化或触发事件时,更新窗口
来源:https://blog.csdn.net/ZJF010101/article/details/124076084


猜你喜欢
- 一.创建正则表达式1.re模块 所有python的正则表达式都在re模块中,使用时导入import rere模块的compile(
- 首先,大家先去下载一份dvbbs.php beta1的代码,解压后先抛开php代码,找出你的mysql手册,如果没有手册那么就直接看下面的实
- 今天在使用PyTorch中Dataset遇到了一个问题。先看代码class psDataset(Dataset): def __
- 以前我浏览博客的时候记得别人说过,BCELoss与CrossEntropyLoss都是用于分类问题。可以知道,BCELoss是Binary
- SCRIPT 标记 用于包含JavaScript代码. 属性 LANGUAGE&nbs
- 提到SQL Server 2005证书,很多人可能以为它只是用来在传输数据的时候起到加密作用的,但在深入了解后,你会发现它的用处还有很多。
- 这篇博客对于考公人或者其他用华图或者粉笔做题的人比较友好,通过输入网址可以自动化获取华图以及粉笔练习的错题。粉笔网站我们从做过的题目组中获取
- 前端开发环境多数基于Node.js,好处不多说了。但与使用Visual Studio开发的后端Asp.Net Core项目一起调试,却不是很
- Vue页面、组件之间传参方式繁多,此处罗列出常用的几种方式,欢迎审阅补充。一丶路由传参这里的路由传参以编程式 router.push(...
- 深入作用域链与闭包为什么要把作用域链和闭包放在一起讲呢,它们有什么关联吗?试想,我们如果在一个内部的函数使用了外部的变量,是通过[[oute
- 本文实例讲述了js模仿php中strtotime()与date()函数实现方法。分享给大家供大家参考。具体如下:在js中没有像php中str
- 前言1.装饰器本质是一个语法糖,是对被装饰方法或类进行的功能扩充,是一种面向切面的实现方法2.装饰器可以分成方法装饰器和类装饰器,他们的区别
- Python 的datetime模块 其实就是date和time 模块的结合,常见的属性方法都比较常用 比如: datetime.day,d
- 写一个 python 脚本需要用到 dbus,但因为 dbus-python 这个包并没有提供 setup.py , 所以无法通过 pip
- 前言随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数
- 听说有个面试题是: 如何快速向mysql中插入1000w条数据?我私下试了一下, 发现插入10000条数据用了0.9s, 插入10w条数据用
- string是c#中的类 String是.net Framework的类 用string需要通过再次编译,所以直接用String速度会更快·
- 很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。比如:select *
- 文件名:Awa_temp.Class.asp 代码如下:<% 'Crazy蛙!模板操作类 '作者C
- 视频观看视频敌人精灵这是我们“Shmup”项目的第2部分!在本课中,我们将添加一些敌人的精灵供玩家躲