以下是Python用tkinter程序做扫雷游戏的代码,带有注释,方便理解:

import tkinter as tk
import random

# 定义常量
MINE = 10
SIZE = 30
WIDTH = 9
HEIGHT = 9

class MineSweeper:
    def __init__(self):
        # 创建主窗口
        self.root = tk.Tk()
        self.root.title('扫雷游戏')
        self.root.resizable(width=False, height=False)

        # 创建游戏区域
        self.canvas = tk.Canvas(self.root,
                                width=WIDTH*SIZE,
                                height=HEIGHT*SIZE)
        self.canvas.pack()

        # 初始化游戏
        self.init_game()

        # 绑定事件
        self.canvas.bind('<Button-1>', self.left_click)
        self.canvas.bind('<Button-3>', self.right_click)
        self.canvas.bind('<Button-2>', self.init_game)

        # 进入主循环
        self.root.mainloop()

    def init_game(self, event=None):
        # 清空游戏区域
        self.canvas.delete('all')

        # 初始化状态数组
        self.status = [[0 for j in range(WIDTH)] for i in range(HEIGHT)]

        # 随机布雷
        self.mines = []
        while len(self.mines) < MINE:
            mine = (random.randint(0, WIDTH-1), random.randint(0, HEIGHT-1))
            if mine not in self.mines:
                self.mines.append(mine)

        # 绘制格子
        for i in range(HEIGHT):
            for j in range(WIDTH):
                x1, y1 = j*SIZE, i*SIZE
                x2, y2 = x1+SIZE, y1+SIZE
                self.canvas.create_rectangle(x1, y1, x2, y2, fill='gray')

        # 绘制雷
        for mine in self.mines:
            x1, y1 = mine[0]*SIZE, mine[1]*SIZE
            x2, y2 = x1+SIZE, y1+SIZE
            self.canvas.create_oval(x1+3, y1+3, x2-3, y2-3, fill='black')

        # 更新状态数组
        for mine in self.mines:
            for i in range(mine[1]-1, mine[1]+2):
                for j in range(mine[0]-1, mine[0]+2):
                    if i<0 or j<0 or i>=HEIGHT or j>=WIDTH or (i,j) in self.mines:
                        continue
                    self.status[i][j] += 1

    def left_click(self, event):
        # 获取点击位置
        x, y = event.x//SIZE, event.y//SIZE

        # 如果点到雷,游戏结束
        if (x, y) in self.mines:
            self.game_over()

        # 如果点到空白格子,递归展开周围的格子
        elif self.status[y][x] == 0:
            self.canvas.create_rectangle(x*SIZE, y*SIZE, (x+1)*SIZE, (y+1)*SIZE, fill='white')
            self.status[y][x] = -1
            for i in range(y-1, y+2):
                for j in range(x-1, x+2):
                    if i<0 or j<0 or i>=HEIGHT or j>=WIDTH or self.status[i][j] != 0:
                        continue
                    self.left_click(tk.Event(type='Button-1', x=(j+0.5)*SIZE, y=(i+0.5)*SIZE))

        # 如果点到数字格子,展示数字
        else:
            self.canvas.create_text((x+0.5)*SIZE, (y+0.5)*SIZE, text=str(self.status[y][x]))

        # 检查游戏是否胜利
        self.check_win()

    def right_click(self, event):
        # 获取点击位置
        x, y = event.x//SIZE, event.y//SIZE

        # 如果是未翻开的格子,标记为雷
        if self.status[y][x] == 0:
            self.canvas.create_text((x+0.5)*SIZE, (y+0.5)*SIZE, text='X', fill='red')
            self.status[y][x] = -2

        # 如果是已标记的格子,取消标记
        elif self.status[y][x] == -2:
            self.canvas.create_rectangle(x*SIZE, y*SIZE, (x+1)*SIZE, (y+1)*SIZE, fill='gray')
            self.status[y][x] = 0

        # 检查游戏是否胜利
        self.check_win()

    def game_over(self):
        # 展示所有雷的位置
        for mine in self.mines:
            x1, y1 = mine[0]*SIZE, mine[1]*SIZE
            x2, y2 = x1+SIZE, y1+SIZE
            self.canvas.create_oval(x1+3, y1+3, x2-3, y2-3, fill='red')

        # 弹出游戏结束的提示框
        tk.messagebox.showinfo('游戏结束', '很遗憾,你输了!')

    def check_win(self):
        # 判断游戏是否胜利
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if self.status[i][j] == 0:
                    return
        tk.messagebox.showinfo('游戏结束', '恭喜你,你赢了!')

# 启动游戏
if __name__ == '__main__':
    minesweeper = MineSweeper()

在代码中,我们首先定义了一些常量,包括:

  • MINE:雷的数量
  • SIZE:每个格子的大小
  • WIDTH:游戏区域的宽度(格子数)
  • HEIGHT:游戏区域的高度(格子数)

然后,我们定义了一个 MineSweeper 类,表示扫雷游戏。在类的 __init__() 方法中,我们创建了主窗口、游戏区域,初始化游戏,并绑定了鼠标事件。

init_game() 方法中,我们清空游戏区域,初始化状态数组,随机布雷,绘制格子和雷,并更新状态数组。

left_click() 方法中,我们获取点击位置,判断是否点到雷、空白格子或数字格子,并做出相应的反应。如果点到空白格子,我们递归展开周围的格子,直到遇到数字格子或边界。如果点到数字格子,我们展示数字。最后,我们检查游戏是否胜利,如果胜利,弹出提示框。

right_click() 方法中,我们获取点击位置,判断格子的状态,并做出相应的反应。如果格子未翻开,我们标记为雷;如果格子已标记,我们取消标记。最后,我们检查游戏是否胜利,如果胜利,弹出提示框。

game_over() 方法中,我们展示所有雷的位置,并弹出游戏结束的提示框。

check_win() 方法中,我们判断游戏是否胜利。如果所有空白格子和数字格子都已翻开,游戏胜利。

最后,我们在 __main__ 中启动游戏

python用tkinter程序做扫雷游戏代码有注释

原文地址: https://www.cveoy.top/t/topic/eE07 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录