佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > python用tkinter開發(fā)的掃雷游戲

python用tkinter開發(fā)的掃雷游戲

熱門標(biāo)簽:鐵路電話系統(tǒng) 呼叫中心市場(chǎng)需求 服務(wù)器配置 網(wǎng)站文章發(fā)布 銀行業(yè)務(wù) 檢查注冊(cè)表項(xiàng) 智能手機(jī) 美圖手機(jī)

1.實(shí)現(xiàn)效果

2.實(shí)現(xiàn)代碼

# 導(dǎo)入所需庫(kù)
from tkinter import *
import random

class main:
    # 定義一個(gè)類,繼承 tkinter 的 Button
    # 用來(lái)保存按鈕的狀態(tài)和在網(wǎng)格布局中的位置
    class minebtn(Button):
        def __init__(self,master,xy,**kw):
            Button.__init__(self,master,**kw)
            self.xy = xy
            self._state = 0
            # 狀態(tài)
            # 0: 未點(diǎn)開
            # 1: 已點(diǎn)開
            # 2: 標(biāo)記
            # 3: 問號(hào)
            
    def __init__(self):
        # 定義規(guī)格及雷數(shù)
        self.width = 9
        self.height = 9
        self.minenum = 10
        # Windows 7 默認(rèn)的三種規(guī)格和雷數(shù)
        # 9*9,10
        # 16*16,40
        # 16*32,99
        
        self.rest = self.minenum    # 剩余未標(biāo)記的雷
		
		# 雷數(shù)的顏色
        self.colorlist = ['green',	# 綠色
                          'DodgerBlue',	# 淺藍(lán)色
                          'DarkOrange1',# 橙色
                          'blue',	# 藍(lán)色
                          '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)  # 隨機(jī)抽取雷
        self.mineplace = [(x%self.width,x//self.height) for x in self.mineplace]    # 將雷的序號(hào)轉(zhuǎn)變?yōu)樽鴺?biāo)

        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))   # 左鍵單擊點(diǎn)開
                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()

    # 點(diǎn)開
    def _open(self,widget):
        xy = widget.xy
        x = xy[0]
        y = xy[1]   # 獲取當(dāng)前按鈕的坐標(biāo)

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

        # 如果已經(jīng)點(diǎn)開了就什么也不做
        if widget._state == 1:
            return
        
        widget.configure(relief='flat',bg='white')  # 更改當(dāng)前按鈕的樣式
        
        widget._state = 1   # 按鈕狀態(tài)設(shè)為點(diǎn)開

        # 獲取周圍八個(gè)雷的坐標(biāo)
        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:
            # 排除掉在雷區(qū)之外的雷
            if 0 = o = self.width - 1 and 0 = p = self.height - 1:
                around_.append((o,p))

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

        #如果周圍沒有雷則打開周圍未標(biāo)記的雷,直到有雷為止
        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   # 顯示雷數(shù)

            # 對(duì)應(yīng)數(shù)字設(shè)置對(duì)應(yīng)顏色
            widget['fg'] = self.colorlist[_sum-1]

    # 右鍵單擊設(shè)置標(biāo)記/問號(hào)
    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()


3.另一種精致一點(diǎn)的實(shí)現(xiàn)

項(xiàng)目地址

需要導(dǎo)入額外的圖片和字體資源,在上面的項(xiàng)目地址里可以下載到

代碼

import sys
import time
import random
import pygame
from pygame.locals import *

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 16
# 塊大小
SIZE = 20
# 地雷數(shù)
MINE_COUNT = 66
# 未點(diǎn)擊
normal = 1
# 已點(diǎn)擊
opened = 2
# 地雷
mine = 3
# 標(biāo)記為地雷
flag = 4
# 標(biāo)記為問號(hào)
ask = 5
# 踩中地雷
bomb = 6
# 被雙擊的周圍
hint = 7
# 正被鼠標(biāo)左右鍵雙擊
double = 8
readied = 1,
started = 2,
over = 3,
win = 4

class Mine:
    def __init__(self, x, y, value=0):
        self._x = x
        self._y = y
        self._value = 0
        self._around_mine_count = -1
        self._status = normal
        self.set_value(value)
    def __repr__(self):
        return str(self._value)
    def get_x(self):
        return self._x
    def set_x(self, x):
        self._x = x
    x = property(fget=get_x, fset=set_x)
    def get_y(self):
        return self._y
    def set_y(self, y):
        self._y = y
    y = property(fget=get_y, fset=set_y)
    def get_value(self):
        return self._value
    def set_value(self, value):
        if value:
            self._value = 1
        else:
            self._value = 0
    value = property(fget=get_value, fset=set_value, doc='0:非地雷 1:雷')
    def get_around_mine_count(self):
        return self._around_mine_count
    def set_around_mine_count(self, around_mine_count):
        self._around_mine_count = around_mine_count
    around_mine_count = property(fget=get_around_mine_count, fset=set_around_mine_count, doc='四周地雷數(shù)量')
    def get_status(self):
        return self._status
    def set_status(self, value):
        self._status = value
    status = property(fget=get_status, fset=set_status, doc='BlockStatus')

class MineBlock:
    def __init__(self):
        self._block = [[Mine(i, j) for i in range(BLOCK_WIDTH)] for j in range(BLOCK_HEIGHT)]
        # 埋雷
        for i in random.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):
            self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1
    def get_block(self):
        return self._block
    block = property(fget=get_block)
    def getmine(self, x, y):
        return self._block[y][x]
    def open_mine(self, x, y):
        # 踩到雷了
        if self._block[y][x].value:
            self._block[y][x].status = bomb
            return False
        # 先把狀態(tài)改為 opened
        self._block[y][x].status = opened
        around = _get_around(x, y)
        _sum = 0
        for i, j in around:
            if self._block[j][i].value:
                _sum += 1
        self._block[y][x].around_mine_count = _sum
        # 如果周圍沒有雷,那么將周圍 8 個(gè)未中未點(diǎn)開的遞歸算一遍
        if _sum == 0:
            for i, j in around:
                if self._block[j][i].around_mine_count == -1:
                    self.open_mine(i, j)
        return True
    def double_mouse_button_down(self, x, y):
        if self._block[y][x].around_mine_count == 0:
            return True
        self._block[y][x].status = double
        around = _get_around(x, y)
        # 周圍被標(biāo)記的雷數(shù)量
        sumflag = 0
        for i, j in _get_around(x, y):
            if self._block[j][i].status == flag:
                sumflag += 1
        # 周邊的雷已經(jīng)全部被標(biāo)記
        result = True
        if sumflag == self._block[y][x].around_mine_count:
            for i, j in around:
                if self._block[j][i].status == normal:
                    if not self.open_mine(i, j):
                        result = False
        else:
            for i, j in around:
                if self._block[j][i].status == normal:
                    self._block[j][i].status = hint
        return result
    def double_mouse_button_up(self, x, y):
        self._block[y][x].status = opened
        for i, j in _get_around(x, y):
            if self._block[j][i].status == hint:
                self._block[j][i].status = normal

# 返回 (x, y) 周圍的點(diǎn)坐標(biāo)
def _get_around(x, y):
    return [(i, j) for i in range(max(0, x - 1), min(BLOCK_WIDTH - 1, x + 1) + 1)
            for j in range(max(0, y - 1), min(BLOCK_HEIGHT - 1, y + 1) + 1) if i != x or j != y]

# 游戲屏幕的寬
SCREEN_WIDTH = BLOCK_WIDTH * SIZE
# 游戲屏幕的高
SCREEN_HEIGHT = (BLOCK_HEIGHT + 2) * SIZE

def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText = font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))

def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('掃雷')
    # 得分的字體
    font1 = pygame.font.Font('resources/a.TTF', SIZE * 2)
    fwidth, fheight = font1.size('999')
    red = (200, 40, 40)

    # 加載資源圖片,因?yàn)橘Y源文件大小不一,所以做了統(tǒng)一的縮放處理
    img0 = pygame.image.load('resources/0.bmp').convert()
    img0 = pygame.transform.smoothscale(img0, (SIZE, SIZE))
    img1 = pygame.image.load('resources/1.bmp').convert()
    img1 = pygame.transform.smoothscale(img1, (SIZE, SIZE))
    img2 = pygame.image.load('resources/2.bmp').convert()
    img2 = pygame.transform.smoothscale(img2, (SIZE, SIZE))
    img3 = pygame.image.load('resources/3.bmp').convert()
    img3 = pygame.transform.smoothscale(img3, (SIZE, SIZE))
    img4 = pygame.image.load('resources/4.bmp').convert()
    img4 = pygame.transform.smoothscale(img4, (SIZE, SIZE))
    img5 = pygame.image.load('resources/5.bmp').convert()
    img5 = pygame.transform.smoothscale(img5, (SIZE, SIZE))
    img6 = pygame.image.load('resources/6.bmp').convert()
    img6 = pygame.transform.smoothscale(img6, (SIZE, SIZE))
    img7 = pygame.image.load('resources/7.bmp').convert()
    img7 = pygame.transform.smoothscale(img7, (SIZE, SIZE))
    img8 = pygame.image.load('resources/8.bmp').convert()
    img8 = pygame.transform.smoothscale(img8, (SIZE, SIZE))
    img_blank = pygame.image.load('resources/blank.bmp').convert()
    img_blank = pygame.transform.smoothscale(img_blank, (SIZE, SIZE))
    img_flag = pygame.image.load('resources/flag.bmp').convert()
    img_flag = pygame.transform.smoothscale(img_flag, (SIZE, SIZE))
    img_ask = pygame.image.load('resources/ask.bmp').convert()
    img_ask = pygame.transform.smoothscale(img_ask, (SIZE, SIZE))
    img_mine = pygame.image.load('resources/mine.bmp').convert()
    img_mine = pygame.transform.smoothscale(img_mine, (SIZE, SIZE))
    img_blood = pygame.image.load('resources/blood.bmp').convert()
    img_blood = pygame.transform.smoothscale(img_blood, (SIZE, SIZE))
    img_error = pygame.image.load('resources/error.bmp').convert()
    img_error = pygame.transform.smoothscale(img_error, (SIZE, SIZE))
    face_size = int(SIZE * 1.25)
    img_face_fail = pygame.image.load('resources/face_fail.bmp').convert()
    img_face_fail = pygame.transform.smoothscale(img_face_fail, (face_size, face_size))
    img_face_normal = pygame.image.load('resources/face_normal.bmp').convert()
    img_face_normal = pygame.transform.smoothscale(img_face_normal, (face_size, face_size))
    img_face_success = pygame.image.load('resources/face_success.bmp').convert()
    img_face_success = pygame.transform.smoothscale(img_face_success, (face_size, face_size))
    face_pos_x = (SCREEN_WIDTH - face_size) // 2
    face_pos_y = (SIZE * 2 - face_size) // 2
    img_dict = {0: img0, 1: img1, 2: img2, 3: img3, 4: img4, 5: img5, 6: img6, 7: img7, 8: img8}
    bgcolor = (225, 225, 225)
    block = MineBlock()
    game_status = readied
    # 開始時(shí)間
    start_time = None
    # 耗時(shí)
    elapsed_time = 0
    while True:
        screen.fill(bgcolor)
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                mouse_x, mouse_y = event.pos
                x = mouse_x // SIZE
                y = mouse_y // SIZE - 2
                b1, b2, b3 = pygame.mouse.get_pressed()
                if game_status == started:
                    # 鼠標(biāo)左右鍵同時(shí)按下,如果已經(jīng)標(biāo)記了所有雷,則打開周圍一圈;如果還未標(biāo)記完所有雷,則有一個(gè)周圍一圈被同時(shí)按下的效果
                    if b1 and b3:
                        mine = block.getmine(x, y)
                        if mine.status == opened:
                            if not block.double_mouse_button_down(x, y):
                                game_status = over
            elif event.type == MOUSEBUTTONUP:
                if y  0:
                    if face_pos_x = mouse_x = face_pos_x + face_size \

                            and face_pos_y = mouse_y = face_pos_y + face_size:
                        game_status = readied
                        block = MineBlock()
                        start_time = time.time()
                        elapsed_time = 0
                        continue
                if game_status == readied:
                    game_status = started
                    start_time = time.time()
                    elapsed_time = 0
                if game_status == started:
                    mine = block.getmine(x, y)
                    # 按鼠標(biāo)左鍵
                    if b1 and not b3:
                        if mine.status == normal:
                            if not block.open_mine(x, y):
                                game_status = over
                    # 按鼠標(biāo)右鍵
                    elif not b1 and b3:
                        if mine.status == normal:
                            mine.status = flag
                        elif mine.status == flag:
                            mine.status = ask
                        elif mine.status == ask:
                            mine.status = normal
                    elif b1 and b3:
                        if mine.status == double:
                            block.double_mouse_button_up(x, y)
        flag_count = 0
        opened_count = 0
        for row in block.block:
            for mine in row:
                pos = (mine.x * SIZE, (mine.y + 2) * SIZE)
                if mine.status == opened:
                    screen.blit(img_dict[mine.around_mine_count], pos)
                    opened_count += 1
                elif mine.status == double:
                    screen.blit(img_dict[mine.around_mine_count], pos)
                elif mine.status == bomb:
                    screen.blit(img_blood, pos)
                elif mine.status == flag:
                    screen.blit(img_flag, pos)
                    flag_count += 1
                elif mine.status == ask:
                    screen.blit(img_ask, pos)
                elif mine.status == hint:
                    screen.blit(img0, pos)
                elif game_status == over and mine.value:
                    screen.blit(img_mine, pos)
                elif mine.value == 0 and mine.status == flag:
                    screen.blit(img_error, pos)
                elif mine.status == normal:
                    screen.blit(img_blank, pos)
        print_text(screen, font1, 30, (SIZE * 2 - fheight) // 2 - 2, '%02d' % (MINE_COUNT - flag_count), red)
        if game_status == started:
            elapsed_time = int(time.time() - start_time)
        print_text(screen, font1, SCREEN_WIDTH - fwidth - 30, (SIZE * 2 - fheight) // 2 - 2, '%03d' % elapsed_time, red)
        if flag_count + opened_count == BLOCK_WIDTH * BLOCK_HEIGHT:
            game_status = win
        if game_status == over:
            screen.blit(img_face_fail, (face_pos_x, face_pos_y))
        elif game_status == win:
            screen.blit(img_face_success, (face_pos_x, face_pos_y))
        else:
            screen.blit(img_face_normal, (face_pos_x, face_pos_y))
        pygame.display.update()

if __name__ == '__main__':
    main()

以上就是python用tkinter開發(fā)的掃雷游戲的詳細(xì)內(nèi)容,更多關(guān)于python 掃雷游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • python實(shí)現(xiàn)掃雷游戲的示例
  • python實(shí)現(xiàn)掃雷小游戲
  • python實(shí)現(xiàn)掃雷游戲
  • 用python寫掃雷游戲?qū)嵗a分享
  • 基于Python實(shí)現(xiàn)的掃雷游戲?qū)嵗a
  • python實(shí)戰(zhàn)游戲之史上最難最虐的掃雷游戲沒有之一

標(biāo)簽:沈陽(yáng) 上海 河南 滄州 長(zhǎng)治 紅河 樂山 新疆

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《python用tkinter開發(fā)的掃雷游戲》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    兴化市| 治多县| 象州县| 永泰县| 将乐县| 赤壁市| 临沭县| 馆陶县| 井冈山市| 垣曲县| 昭通市| 巫山县| 务川| 上栗县| 佛教| 尉氏县| 大渡口区| 黑河市| 宜昌市| 巴中市| 隆德县| 深水埗区| 枣庄市| 延津县| 施甸县| 吉隆县| 上饶市| 东阳市| 彰武县| 金昌市| 潼南县| 和平县| 新宁县| 邹平县| 临漳县| 苍溪县| 台安县| 万州区| 翼城县| 崇仁县| 铜梁县|