基于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()
相关推荐
oyishyi22 分钟前
从零开始独立游戏开发学习笔记(七十八)--绘画/像素画学习笔记(十五)--V大预科3.0(五)-第三,四周理论
游戏·游戏开发
虾球xz27 分钟前
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
开发语言·c++·物联网·学习
工业互联网专业34 分钟前
基于django+vue的健身房管理系统-vue
vue.js·python·django·毕业设计·源码·课程设计·健身房管理系统
aischang1 小时前
统信桌面专业版如何使用python开发平台jupyter
开发语言·python·jupyter·统信uos
红鼻子时代1 小时前
Django RBAC项目后端实战 - 03 DRF权限控制实现
后端·python·django·rabc
敲键盘的小夜猫1 小时前
大模型链路调试平台之LangSmith实战指南
python·langchain
狐凄1 小时前
Python实例题:Python计算概率论
开发语言·python·概率论
Y3174291 小时前
python Day46 学习(日志Day15复习)
python·学习·机器学习
这里有鱼汤1 小时前
一文读懂量化交易中最常用的5种均线,附源码,建议收藏
后端·python
学不会就看2 小时前
selenium学习实战【Python爬虫】
python·学习·selenium