網站首頁 編程語言 正文
前言
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()#監控組件,組件發生變化或觸發事件時,更新窗口
總結
掃雷的思路簡單,但編寫這個程序仍然花費了我比較長的時間,究其原因:初次接觸python的GUI編程,對各個控件的方法等不熟悉,且沒有能夠充分的查找資料,在面對問題時處理思路局限。編程世界,道路漫長遙遠。
原文鏈接:https://blog.csdn.net/ZJF010101/article/details/124076084
相關推薦
- 2022-05-31 Python學習之日志模塊詳解_python
- 2022-03-15 PEM_read_bio_X509_AUX() failed (SSL: error:0906D06
- 2022-06-18 基于Python實現實時監控CPU使用率_python
- 2022-03-14 C語言撲克牌游戲示例(c語言紙牌游戲)
- 2022-07-18 Maven快照更新策略
- 2022-09-24 Go?select使用與底層原理講解_Golang
- 2022-11-22 react?hooks實現原理解析_React
- 2023-03-22 Linux?rm命令詳解?Linux刪除文件目錄的操作方法_linux shell
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支