扫雷小游戏代码。供消遣娱乐:

import tkinter as tk
from tkinter import messagebox
import random
# 游戏参数(中等难度:15x15 网格,40 颗雷)
ROWS = 15
COLS = 15
MINES = 40
CELL_SIZE = 30
COLORS = {
'default': '#CCCCCC',
'opened': '#FFFFFF',
'mine': '#FF0000',
'flag': '#00FF00',
'text': '#000000'
}
class Minesweeper:
def __init__(self):
self.window = tk.Tk()
self.window.title("扫雷游戏 - 中级")
self.board = []
self.mines = set()
self.flags = set()
self.opened = set()
self.game_over = False
self.start_time = None
self.timer = 0
# 初始化界面
self.create_widgets()
self.generate_mines()
self.update_timer()
self.window.mainloop()
def create_widgets(self):
self.timer_label = tk.Label(self.window, text="时间: 0", font=('Arial', 12))
self.timer_label.grid(row=0, column=0, columnspan=COLS)
self.mine_label = tk.Label(self.window, text=f"剩余雷数: {MINES}", font=('Arial', 12))
self.mine_label.grid(row=0, column=COLS-2, columnspan=2)
self.canvas = tk.Canvas(self.window, width=COLS*CELL_SIZE, height=ROWS*CELL_SIZE)
self.canvas.grid(row=1, column=0, columnspan=COLS)
# 绘制网格
for x in range(COLS):
for y in range(ROWS):
self.board.append((x, y))
self.canvas.create_rectangle(
x*CELL_SIZE, y*CELL_SIZE,
(x+1)*CELL_SIZE, (y+1)*CELL_SIZE,
fill=COLORS['default'], outline='black'
)
self.canvas.bind('<Button-1>', self.left_click)
self.canvas.bind('<Button-3>', self.right_click)
def generate_mines(self):
self.mines = set(random.sample(self.board, MINES))
def count_nearby_mines(self, x, y):
count = 0
for dx in (-1, 0, 1):
for dy in (-1, 0, 1):
if (dx, dy) == (0, 0):
continue
if (x+dx, y+dy) in self.mines:
count += 1
return count
def left_click(self, event):
if self.game_over:
return
if not self.start_time:
self.start_time = True
self.window.after(1000, self.update_timer)
x = event.x // CELL_SIZE
y = event.y // CELL_SIZE
cell = (x, y)
if cell in self.flags:
return
if cell in self.mines:
self.game_over = True
self.reveal_mines()
messagebox.showerror("游戏结束", "你踩到地雷了!")
self.window.destroy()
else:
self.open_cell(x, y)
def right_click(self, event):
if self.game_over:
return
x = event.x // CELL_SIZE
y = event.y // CELL_SIZE
cell = (x, y)
if cell in self.opened:
return
if cell in self.flags:
self.flags.remove(cell)
self.canvas.itemconfig(self.get_cell_id(x, y), fill=COLORS['default'])
else:
self.flags.add(cell)
self.canvas.itemconfig(self.get_cell_id(x, y), fill=COLORS['flag'])
self.mine_label.config(text=f"剩余雷数: {MINES - len(self.flags)}")
def open_cell(self, x, y):
if (x, y) in self.opened:
return
self.opened.add((x, y))
count = self.count_nearby_mines(x, y)
cell_id = self.get_cell_id(x, y)
self.canvas.itemconfig(cell_id, fill=COLORS['opened'])
if count > 0:
self.canvas.create_text(
x*CELL_SIZE + CELL_SIZE//2,
y*CELL_SIZE + CELL_SIZE//2,
text=str(count), fill=COLORS['text'], font=('Arial', 12)
)
else:
# 递归打开相邻空白格
for dx in (-1, 0, 1):
for dy in (-1, 0, 1):
nx, ny = x+dx, y+dy
if 0 <= nx < COLS and 0 <= ny < ROWS:
self.open_cell(nx, ny)
if len(self.opened) + MINES == ROWS*COLS:
messagebox.showinfo("胜利", "你成功排除了所有地雷!")
self.window.destroy()
def get_cell_id(self, x, y):
return self.canvas.find_closest(x*CELL_SIZE + CELL_SIZE//2, y*CELL_SIZE + CELL_SIZE//2)[0]
def reveal_mines(self):
for (x, y) in self.mines:
self.canvas.itemconfig(self.get_cell_id(x, y), fill=COLORS['mine'])
def update_timer(self):
if self.start_time and not self.game_over:
self.timer += 1
self.timer_label.config(text=f"时间: {self.timer}")
self.window.after(1000, self.update_timer)
if __name__ == "__main__":
Minesweeper()