python 用 tkinter 開發簡單掃雷小游戲


1. 掃雷游戲

效果

 

 3

 

2. 代碼

# 導入所需庫
from tkinter import *
import random

class main:
    # 定義一個類,繼承 tkinter 的 Button
    # 用來保存按鈕的狀態和在網格布局中的位置
    class minebtn(Button):
        def __init__(self,master,xy,**kw):
            Button.__init__(self,master,**kw)
            self.xy = xy
            self._state = 0
            # 狀態
            # 0: 未點開
            # 1: 已點開
            # 2: 標記
            # 3: 問號
            
    def __init__(self):
        # 定義規格及雷數
        self.width = 9
        self.height = 9
        self.minenum = 10
        # Windows 7 默認的三種規格和雷數
        # 9*9,10
        # 16*16,40
        # 16*32,99
        
        self.rest = self.minenum    # 剩余未標記的雷
        
        # 雷數的顏色
        self.colorlist = ['green',    # 綠色
                          'DodgerBlue',    # 淺藍色
                          'DarkOrange1',# 橙色
                          'blue',    # 藍色
                          'red',    # 紅色
                          'Chocolate4',    # 棕色
                          'grey',    # 灰色
                          'black']    # 黑色
        
        self.setgui()

    def setgui(self):

        # GUI界面

        self.root = Tk()
        self.root.title('掃雷')

        self.restlabel = Label(self.root,text=f'剩余:{self.minenum}')
        self.restlabel.grid(row=0,column=0,columnspan=3)

        self.mineplace = random.sample(range(self.width*self.height),self.minenum)  # 隨機抽取雷
        self.mineplace = [(x%self.width,x//self.height) for x in self.mineplace]    # 將雷的序號轉變為坐標

        self.mines = {}

        for y in range(self.height):
            for x in range(self.width):
                self.mines[(x,y)] = self.minebtn(self.root,xy=(x,y),font=('黑體',8,'bold'),width=2,bd=1,relief='ridge')
                self.mines[(x,y)].bind('<ButtonRelease-1>',lambda event:self._open(event.widget))   # 左鍵單擊點開
                self.mines[(x,y)].bind('<ButtonRelease-3>',lambda event:self.make(event.widget))    # 右鍵單擊事件
                self.mines[(x,y)].grid(row=y+1,column=x,sticky='nswe')

        self.root.mainloop()

    # 點開
    def _open(self,widget):
        xy = widget.xy
        x = xy[0]
        y = xy[1]   # 獲取當前按鈕的坐標

        # 如果是雷則顯示全部雷的位置
        if widget.xy in self.mineplace:
            self.showmine()
            return

        # 如果已經點開了就什么也不做
        if widget._state == 1:
            return
        
        widget.configure(relief='flat',bg='white')  # 更改當前按鈕的樣式
        
        widget._state = 1   # 按鈕狀態設為點開

        # 獲取周圍八個雷的坐標
        around = [(x-1,y-1),
                (x,y-1),
                (x+1,y-1),
                (x-1,y),
                (x+1,y),
                (x-1,y+1),
                (x,y+1),
                (x+1,y+1)]
        
        _sum = 0
        around_ = []
        
        for o, p in around:
            # 排除掉在雷區之外的雷
            if 0 <= o <= self.width - 1 and 0 <= p <= self.height - 1:
                around_.append((o,p))

                # 計算周圍的雷數
                if self.mines[(o,p)].xy in self.mineplace:
                    _sum += 1

        #如果周圍沒有雷則打開周圍未標記的雷,直到有雷為止
        if _sum == 0:
            widget['text'] = ''

            for i, j in around:                
                if self.mines[(i,j)]._state == 0:
                    self._open(self.mines[(i,j)])
        else:
            widget['text'] = _sum   # 顯示雷數

            # 對應數字設置對應顏色
            widget['fg'] = self.colorlist[_sum-1]

    # 右鍵單擊設置標記/問號
    def make(self,widget):
        string = {0:'',2:'',3:'?'}
        
        if widget._state == 0:
            widget._state = 2
            widget['text'] = string[2]
            self.rest -= 1
            self.restlabel['text'] = f'剩余:{self.rest}'
            
        elif widget._state == 2:
            widget._state = 3
            widget['text'] = string[3]
            self.rest += 1
            self.restlabel['text'] = f'剩余:{self.rest}'
            
        elif widget._state == 3:
            widget._state = 0
            widget['text'] = string[0]

    # 如果踩到雷,顯示所有的雷
    def showmine(self):
        for i, j in self.mineplace:
            self.mines[(i,j)].configure(text='ி',fg='red')
                
main()

因為這個網絡游戲比較簡單,也有游戲可以作為參考,所以相對得沒有那么難,代碼也就沒有那么多了,希望各位能夠看得懂哦!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM