【tkinter】用不到50行Python代码,写一个扫雷小游戏
文章目錄
- 定制按鈕
- 生成雷區(qū)
- 主流程
Tkinter系列:
- GUI初步💎布局💎綁定變量💎綁定事件💎消息框
- 掃雷小游戲💎強(qiáng)行表白神器
定制按鈕
學(xué)會(huì)了布局和綁定事件,就可以開發(fā)一些簡(jiǎn)單的應(yīng)用,比如掃雷小游戲。從外觀來看,掃雷就是一個(gè)按鈕矩陣,左鍵點(diǎn)擊按鈕,如果按鈕里埋了雷,那么就游戲結(jié)束,否則繼續(xù)游戲。
所以第一步,是對(duì)按鈕進(jìn)行定制
import tkinter as tk from itertools import productdef clickRight(evt, txt):if txt.get() == "🚩":txt.set("")else:txt.set("🚩")def clickLeft(evt, txt, isMine):if isMine:txt.set("💥")else:txt.set(" ")def setMine(root, i, j, isMine=False):txt = tk.StringVar()btn = tk.Button(root, width=5, height=2,textvariable=txt)btn.grid(row=i,column=j)btn.bind("<Button-3>", lambda evt: clickRight(evt, txt))btn.bind("<Button-1>", lambda evt: clickLeft(evt, txt, isMine))root = tk.Tk() root.title("掃雷") for i,j in product(range(5), range(8)):setMine(root, i, j, True)root.mainloop()效果如下,總共設(shè)置了40個(gè)按鈕,每個(gè)按鈕都是雷。
生成雷區(qū)
接下來要做的有兩件事,一是隨機(jī)生成一片雷區(qū),二是引發(fā)雷的連鎖反應(yīng),當(dāng)點(diǎn)擊一個(gè)按鈕,如果這個(gè)按鈕不是雷,那么會(huì)顯示這個(gè)按鈕周圍的雷的個(gè)數(shù)。
隨機(jī)雷區(qū)可以通過矩陣實(shí)現(xiàn)
import numpy as np def setMineMat(M, N, r):mat = np.random.rand(M, N)return mat > r其中mat是一個(gè)范圍在0到1之間均勻分布的矩陣,其返回值是一個(gè)布爾型矩陣,True為雷,False為非雷,所以r越大,則True值越少,雷也就越少,也就越簡(jiǎn)單。
然后實(shí)現(xiàn)第二個(gè)需求,當(dāng)左鍵點(diǎn)擊按鈕后,按鈕顯示的值,
def mineNumber(mat, i, j):if mat[i,j] == True:return "💥"M, N = mat.shapei0, i1 = max(0, i-1), min(M, i+2)j0, j1 = max(0, j-1), min(N, j+2)num = np.sum(mat[i0:i1, j0:j1])return str(num)在這個(gè)基礎(chǔ)上,更改左鍵單擊的邏輯,除了點(diǎn)擊之后顯示的內(nèi)容發(fā)生變化之外,若該點(diǎn)為雷,則彈出失敗框;若該點(diǎn)為0,則將該點(diǎn)周圍所有點(diǎn)全部翻面。
from tkinter.messagebox import showerrordef clickRight(evt, txt):if txt.get() == "🚩": txt.set("")else: txt.set("🚩")def clickLeft(i, j):if txtLst[i][j].get() != "":returnflag = mineNumber(mat, i, j)txtLst[i][j].set(flag)if flag == "💥":showerror("", "你輸了!")if flag != "0":returni0, i1 = max(0, i-1), min(M, i+2)j0, j1 = max(0, j-1), min(N, j+2)for i,j in product(range(i0,i1), range(j0, j1)):clickLeft(i, j)重新寫一下生成雷區(qū)的邏輯,按鈕綁定了兩個(gè)事件,分別在左鍵點(diǎn)擊和右鍵點(diǎn)擊時(shí)觸發(fā)。
def setMine(root, i, j):txt = tk.StringVar()btn = tk.Button(root, width=5, height=2,textvariable=txt)btn.grid(row=i,column=j)btn.bind("<Button-3>", lambda evt: clickRight(evt, txt))btn.bind("<Button-1>", lambda evt: clickLeft(i, j))return txt主流程
最后,寫一下主流程
root = tk.Tk() root.title("掃雷")M, N, r = 6, 10, 0.8 mat = setMineMat(M, N, r) txtLst = [[] for _ in range(M)] for i,j in product(range(M), range(N)):txt = setMine(root, i, j)txtLst[i].append(txt)root.mainloop()效果為
這個(gè)掃雷還有一些不足之處,最顯而易見的就是旗幟和雷的顏色,這一點(diǎn)其實(shí)很好辦,只要改下前景就行。另外一點(diǎn)就是,并沒有提供一個(gè)按鈕用于改變雷區(qū)和難度,對(duì)于這點(diǎn),最簡(jiǎn)單的方法既是來一個(gè)參數(shù)對(duì)話框,這個(gè)內(nèi)容接下來就講。
總結(jié)
以上是生活随笔為你收集整理的【tkinter】用不到50行Python代码,写一个扫雷小游戏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝牙mesh- Features和设备类
- 下一篇: pythonturtle画丘比特之箭_p