基于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()
相关推荐
Elastic 中国社区官方博客3 分钟前
Observability:适用于 PHP 的 OpenTelemetry:EDOT PHP 加入 OpenTelemetry 项目
大数据·开发语言·人工智能·elasticsearch·搜索引擎·全文检索·php
csbysj202010 分钟前
PHP 魔术常量
开发语言
神仙别闹18 分钟前
基于 C++和 Python 实现计算机视觉
c++·python·计算机视觉
狮子不白24 分钟前
C#WEB 防重复提交控制
开发语言·前端·程序人生·c#
2501_940094021 小时前
iphone Delta模拟器如何从夸克网盘导入游戏ROM 附游戏资源下载
游戏·ios·iphone
hongjianMa1 小时前
【论文阅读】Hypercomplex Prompt-aware Multimodal Recommendation
论文阅读·python·深度学习·机器学习·prompt·推荐系统
Elnaij1 小时前
从C++开始的编程生活(12)——vector简单介绍和迭代器
开发语言·c++
饼干,2 小时前
第23天python内容
开发语言·python
数学难2 小时前
Java面试题2:Java线程池原理
java·开发语言