我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python用tkinter开发的扫雷游戏

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python用tkinter开发的扫雷游戏

目录
  • 2.实现代码
  • 3.另一种精致一点的实现

1.实现效果

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()


3.另一种精致一点的实现

项目地址

需要导入额外的图片和字体资源,在上面的项目地址里可以下载到

代码


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

BLOCK_WIDTH = 30
BLOCK_HEIGHT = 16
# 块大小
SIZE = 20
# 地雷数
MINE_COUNT = 66
# 未点击
normal = 1
# 已点击
opened = 2
# 地雷
mine = 3
# 标记为地雷
flag = 4
# 标记为问号
ask = 5
# 踩中地雷
bomb = 6
# 被双击的周围
hint = 7
# 正被鼠标左右键双击
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='四周地雷数量')
    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
        # 先把状态改为 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 个未中未点开的递归算一遍
        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)
        # 周围被标记的雷数量
        sumflag = 0
        for i, j in _get_around(x, y):
            if self._block[j][i].status == flag:
                sumflag += 1
        # 周边的雷已经全部被标记
        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) 周围的点坐标
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)

    # 加载资源图片,因为资源文件大小不一,所以做了统一的缩放处理
    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
    # 开始时间
    start_time = None
    # 耗时
    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:
                    # 鼠标左右键同时按下,如果已经标记了所有雷,则打开周围一圈;如果还未标记完所有雷,则有一个周围一圈被同时按下的效果
                    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)
                    # 按鼠标左键
                    if b1 and not b3:
                        if mine.status == normal:
                            if not block.open_mine(x, y):
                                game_status = over
                    # 按鼠标右键
                    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开发的扫雷游戏的详细内容,更多关于python 扫雷游戏的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python用tkinter开发的扫雷游戏

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python用tkinter开发的扫雷游戏

目录2.实现代码3.另一种精致一点的实现1.实现效果2.实现代码# 导入所需库 from tkinter import * import randomclass main:# 定义一个类,继承 tkinter 的 Button# 用来保存按
2022-06-02

如何使用Java开发扫雷游戏

小编给大家分享一下如何使用Java开发扫雷游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、效果图 二、实现思路1.界面上可以点开的各种实际都是按钮
2023-06-15

python 写的扫雷游戏

#!/usr/bin/python#coding:utf-8#python 写的扫雷游戏import sysimport randomclass MineSweeping(): #扫雷主程序 def __init__(self,
2023-01-31

怎么在python中使用tkinter实现一个扫雷游戏

怎么在python中使用tkinter实现一个扫雷游戏?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现代码# 导入所需库from tkinter import
2023-06-15

使用 python 实现单人AI 扫雷游戏

AI玩扫雷 很高兴又见面了!扫雷是一款单人益智游戏,相信大部分人都在以前上微机课的时候玩过。游戏的目标是借助每个区域中相邻地雷数量的线索,清除包含隐藏的“地雷”或炸弹的单元格,但不引爆其中任何一个,全部清除后即可获胜。今天我们用 Pytho
2022-06-02

怎么用Python做了一个Windows扫雷游戏

怎么用Python做了一个Windows扫雷游戏,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Windows XP 上的扫雷是无数80/90后的集体回忆,今天我
2023-06-16

C语言学小游戏开发 简易版扫雷设计教程

编程学习网: 扫雷最初的流行伴随着1992年发布的Windows3.1,之后迅速成为了各种操作系统中必不可少的一款游戏(包括windows的winmine,KDE桌面环境下的KMines,GNOME桌面环境下的gnomine等)。
C语言学小游戏开发 简易版扫雷设计教程
2024-04-23

利用C语言实现一个可展开的扫雷小游戏

利用C语言实现一个可展开的扫雷小游戏?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语
2023-06-06

使用Java实现三种等级的扫雷游戏(完整版)

扫雷是一款大众类的益智小游戏,根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输,下面这篇文章主要给大家介绍了关于使用Java实现三种等级的扫雷游戏的相关资料,需要的朋友可以参考下
2023-01-10

Python开发游戏之井字游戏的实战步骤

最近正在学习Python,所以最近做了一个关于Python的实例,下面这篇文章主要给大家介绍了关于Python开发游戏之井字游戏的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-02-04

python使用pgzero进行游戏开发

目录1. pgzeropgzero的安装2. 游戏设计的过程3. pgzero基础4. pgzero游戏例子5. 总结6. 参考资料1. pgzeropython在各个领域都有着丰富的第三方库,pygame是python在游戏领域的应用库,
2022-06-02

探索Unity3D游戏引擎,开启游戏开发之旅(Unity3D游戏引擎在游戏开发中的应用与探索)

Unity3D是一款跨平台游戏引擎,广泛应用于各类游戏开发,包括3D、2D、移动、VR和AR游戏。其优势在于跨平台支持、强大的图形渲染、物理引擎、友好的用户界面和丰富的工具集。探索Unity3D可通过在线教程、官方文档、社区论坛、资产商店和创建游戏原型等方式,帮助开发人员深入了解引擎的工作原理并将其应用于游戏开发中。
探索Unity3D游戏引擎,开启游戏开发之旅(Unity3D游戏引擎在游戏开发中的应用与探索)
2024-04-02

Python中的游戏开发模块pyglet的用法

这篇文章主要讲解了“Python中的游戏开发模块pyglet的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中的游戏开发模块pyglet的用法”吧!前言为什么我不选择pyga
2023-06-15

如何使用python+pygame开发消消乐游戏

这篇文章主要介绍了如何使用python+pygame开发消消乐游戏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。效果是这样的 ↓ ↓ ↓ 一、环境要求windows系统,py
2023-06-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录