import tkinter as tk from tkinter import messagebox import random class MineSweeper: def __init__(self, master, rows, cols, mines): self.master = master self.rows = rows self.cols = cols self.mines = mines self.buttons = {} self.board = [[0 for _ in range(cols)] for _ in range(rows)] self.revealed = [[False for _ in range(cols)] for _ in range(rows)] self.flags = [[False for _ in range(cols)] for _ in range(rows)] self.game_over = False self.generate_mines() self.create_widgets() def generate_mines(self): count = 0 while count < self.mines: r = random.randint(0, self.rows - 1) c = random.randint(0, self.cols - 1) if self.board[r][c] == -1: continue self.board[r][c] = -1 count += 1 # 更新周围数字 for i in range(r - 1, r + 2): for j in range(c - 1, c + 2): if 0 <= i < self.rows and 0 <= j < self.cols and self.board[i][j] != -1: self.board[i][j] += 1 def create_widgets(self): for r in range(self.rows): for c in range(self.cols): b = tk.Button(self.master, width=2, height=1, font=('Arial', 14), command=lambda r=r, c=c: self.reveal_cell(r, c)) b.bind("", lambda e, r=r, c=c: self.toggle_flag(r, c)) b.grid(row=r, column=c) self.buttons[(r, c)] = b def reveal_cell(self, r, c): if self.game_over or self.revealed[r][c] or self.flags[r][c]: return if self.board[r][c] == -1: self.buttons[(r, c)].config(text="💣", bg="red") self.game_over = True self.show_all_mines() messagebox.showerror("游戏结束", "你踩到雷啦!") return self.flood_fill(r, c) self.check_win() def flood_fill(self, r, c): if not (0 <= r < self.rows and 0 <= c < self.cols): return if self.revealed[r][c] or self.flags[r][c]: return self.revealed[r][c] = True val = self.board[r][c] btn = self.buttons[(r, c)] btn.config(relief=tk.SUNKEN, text=str(val) if val > 0 else "", state=tk.DISABLED, bg="lightgray") if val == 0: for dr in (-1, 0, 1): for dc in (-1, 0, 1): if dr != 0 or dc != 0: self.flood_fill(r + dr, c + dc) def toggle_flag(self, r, c): if self.revealed[r][c] or self.game_over: return if self.flags[r][c]: self.flags[r][c] = False self.buttons[(r, c)].config(text="") else: self.flags[r][c] = True self.buttons[(r, c)].config(text="🚩") def show_all_mines(self): for r in range(self.rows): for c in range(self.cols): if self.board[r][c] == -1: self.buttons[(r, c)].config(text="💣") def check_win(self): for r in range(self.rows): for c in range(self.cols): if self.board[r][c] != -1 and not self.revealed[r][c]: return self.game_over = True messagebox.showinfo("胜利!", "恭喜你,排雷成功!") # 自定义参数 def start_game(): try: rows = int(entry_rows.get()) cols = int(entry_cols.get()) mines = int(entry_mines.get()) if rows <= 0 or cols <= 0 or mines <= 0 or mines >= rows * cols: raise ValueError except: messagebox.showerror("输入错误", "请输入合理的行列和雷数") return settings_window.destroy() root = tk.Tk() root.title("扫雷") MineSweeper(root, rows, cols, mines) root.mainloop() # 设置窗口 settings_window = tk.Tk() settings_window.title("扫雷设置") tk.Label(settings_window, text="行数:").grid(row=0, column=0) entry_rows = tk.Entry(settings_window) entry_rows.insert(0, "10") entry_rows.grid(row=0, column=1) tk.Label(settings_window, text="列数:").grid(row=1, column=0) entry_cols = tk.Entry(settings_window) entry_cols.insert(0, "10") entry_cols.grid(row=1, column=1) tk.Label(settings_window, text="雷数:").grid(row=2, column=0) entry_mines = tk.Entry(settings_window) entry_mines.insert(0, "10") entry_mines.grid(row=2, column=1) tk.Button(settings_window, text="开始游戏", command=start_game).grid(row=3, column=0, columnspan=2) settings_window.mainloop()