基于python的扫雷游戏

游戏

游戏目标:

揭开所有非地雷的格子。

如果揭开地雷,游戏失败。

使用标记功能(🚩)来标记可能的地雷位置。

格子类型:

空白格子:表示周围没有地雷。

数字格子:显示周围 8 个格子中有多少地雷。

地雷格子:揭开后游戏失败。

标记格子:玩家标记为可能的地雷位置。

操作方式:

左键点击:揭开格子。

右键点击:标记或取消标记地雷。

界面

代码

python 复制代码
import tkinter as tk
from tkinter import messagebox
import random

class Minesweeper:
    def __init__(self, root, width=10, height=10, mines=10):
        self.root = root
        self.width = width
        self.height = height
        self.mines = mines
        self.board = [[0 for _ in range(width)] for _ in range(height)]
        self.revealed = [[False for _ in range(width)] for _ in range(height)]
        self.flags = [[False for _ in range(width)] for _ in range(height)]
        self.game_over = False
        self.buttons = [[None for _ in range(width)] for _ in range(height)]
        self.remaining_mines = mines
        self.create_top_panel()
        self.place_mines()
        self.calculate_numbers()
        self.create_widgets()

    def create_top_panel(self):
        self.top_panel = tk.Frame(self.root, bg="lightgray")
        self.top_panel.grid(row=0, column=0, columnspan=self.width, sticky="ew")

        self.mine_label = tk.Label(self.top_panel, text=f"Mines: {self.remaining_mines}", font=("Arial", 12), bg="lightgray")
        self.mine_label.pack(side="left", padx=10)

        self.reset_button = tk.Button(self.top_panel, text="Reset", font=("Arial", 12), command=self.reset_game)
        self.reset_button.pack(side="right", padx=10)

    def place_mines(self):
        mines_placed = 0
        while mines_placed < self.mines:
            x = random.randint(0, self.width - 1)
            y = random.randint(0, self.height - 1)
            if self.board[y][x] != -1:
                self.board[y][x] = -1
                mines_placed += 1

    def calculate_numbers(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] == -1:
                    continue
                count = 0
                for dy in [-1, 0, 1]:
                    for dx in [-1, 0, 1]:
                        if dy == 0 and dx == 0:
                            continue
                        ny, nx = y + dy, x + dx
                        if 0 <= ny < self.height and 0 <= nx < self.width and self.board[ny][nx] == -1:
                            count += 1
                self.board[y][x] = count

    def create_widgets(self):
        for y in range(self.height):
            for x in range(self.width):
                button = tk.Button(
                    self.root,
                    text="",
                    width=2,
                    height=1,
                    font=("Arial", 12, "bold"),
                    relief=tk.RAISED,
                    command=lambda x=x, y=y: self.reveal(x, y),
                )
                button.bind("<Button-3>", lambda event, x=x, y=y: self.toggle_flag(x, y))
                button.grid(row=y + 1, column=x, padx=1, pady=1)
                self.buttons[y][x] = button

    def reveal(self, x, y):
        if self.game_over or self.flags[y][x]:
            return
        if self.board[y][x] == -1:
            self.game_over = True
            self.buttons[y][x].config(text="💣", bg="red", relief=tk.SUNKEN)
            self.show_all_mines()
            messagebox.showinfo("Game Over", "You hit a mine! Game over.")
            return
        self.revealed[y][x] = True
        self.buttons[y][x].config(text=str(self.board[y][x]), relief=tk.SUNKEN, bg="lightgray")
        self.set_number_color(x, y)
        if self.board[y][x] == 0:
            for dy in [-1, 0, 1]:
                for dx in [-1, 0, 1]:
                    if 0 <= y + dy < self.height and 0 <= x + dx < self.width:
                        if not self.revealed[y + dy][x + dx]:
                            self.reveal(x + dx, y + dy)
        if self.check_win():
            messagebox.showinfo("Congratulations!", "You won!")

    def toggle_flag(self, x, y):
        if self.game_over or self.revealed[y][x]:
            return
        self.flags[y][x] = not self.flags[y][x]
        if self.flags[y][x]:
            self.buttons[y][x].config(text="🚩", fg="red")
            self.remaining_mines -= 1
        else:
            self.buttons[y][x].config(text="", fg="black")
            self.remaining_mines += 1
        self.mine_label.config(text=f"Mines: {self.remaining_mines}")

    def set_number_color(self, x, y):
        number = self.board[y][x]
        if number == 1:
            self.buttons[y][x].config(fg="blue")
        elif number == 2:
            self.buttons[y][x].config(fg="green")
        elif number == 3:
            self.buttons[y][x].config(fg="red")
        elif number == 4:
            self.buttons[y][x].config(fg="purple")
        elif number >= 5:
            self.buttons[y][x].config(fg="orange")

    def show_all_mines(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] == -1:
                    self.buttons[y][x].config(text="💣", bg="yellow", relief=tk.SUNKEN)

    def check_win(self):
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x] != -1 and not self.revealed[y][x]:
                    return False
        return True

    def reset_game(self):
        for y in range(self.height):
            for x in range(self.width):
                self.buttons[y][x].config(text="", bg="SystemButtonFace", relief=tk.RAISED, fg="black")
        self.board = [[0 for _ in range(self.width)] for _ in range(self.height)]
        self.revealed = [[False for _ in range(self.width)] for _ in range(self.height)]
        self.flags = [[False for _ in range(self.width)] for _ in range(self.height)]
        self.game_over = False
        self.remaining_mines = self.mines
        self.mine_label.config(text=f"Mines: {self.remaining_mines}")
        self.place_mines()
        self.calculate_numbers()

def main():
    root = tk.Tk()
    root.title("Minesweeper")
    game = Minesweeper(root)
    root.mainloop()

if __name__ == "__main__":
    main()
相关推荐
默_笙4 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_426003964 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技4 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读4 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时4 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
C语言小火车4 天前
C/C++ 为什么需要编译器?
开发语言·c++
奇思妙想聪明勤奋的小羊4 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
lpfasd1234 天前
2026年第38周GitHub趋势周报
python·科技·github