ChatGPT与我们玩游戏_排雷
作者:顾翔import tkinter as tk
import random
import time
class Minesweeper:
def __init__(self, master, width=10, height=10, num_mines=20):
self.master = master
self.master.title("挖地雷")
self.width = width # 网格宽度
self.height = height # 网格高度
self.num_mines = num_mines # 地雷数量
self.buttons = []
self.mines = set() # 存储地雷的坐标
self.revealed = set() # 存储已打开的格子
self.flags = set() # 存储标记的格子
self.game_over = False
# 创建画布和按钮
self.canvas = tk.Canvas(self.master, width=width*30, height=height*30)
self.canvas.pack()
self.create_grid()
self.place_mines()
def create_grid(self):
"""创建按钮网格"""
for row in range(self.height):
button_row = []
for col in range(self.width):
button = tk.Button(self.master, text='', width=3, height=1, command=lambda r=row, c=col: self.reveal(r, c))
button.grid(row=row, column=col)
button_row.append(button)
self.buttons.append(button_row)
def place_mines(self):
"""随机放置地雷"""
while len(self.mines) < self.num_mines:
mine = (random.randint(0, self.height-1), random.randint(0, self.width-1))
self.mines.add(mine)
def reveal(self, row, col):
"""揭示格子内容"""
if self.game_over or (row, col) in self.revealed or (row, col) in self.flags:
return
self.revealed.add((row, col))
if (row, col) in self.mines:
self.buttons[row][col].config(text="💣", bg="red")
self.game_over = True
self.show_game_over("游戏失败!")
return
else:
# 计算相邻地雷的数量
adjacent_mines = self.count_adjacent_mines(row, col)
if adjacent_mines > 0:
self.buttons[row][col].config(text=str(adjacent_mines), relief=tk.SUNKEN)
else:
self.buttons[row][col].config(relief=tk.SUNKEN)
# 如果没有地雷,递归揭示相邻格子
for r in range(max(0, row-1), min(self.height, row+2)):
for c in range(max(0, col-1), min(self.width, col+2)):
if (r, c) != (row, col) and (r, c) not in self.revealed:
self.reveal(r, c)
# 检查游戏胜利条件
if len(self.revealed) == self.width * self.height - self.num_mines:
self.game_over = True
self.show_game_over("游戏胜利!")
def count_adjacent_mines(self, row, col):
"""计算相邻格子的地雷数量"""
adjacent_mines = 0
for r in range(max(0, row-1), min(self.height, row+2)):
for c in range(max(0, col-1), min(self.width, col+2)):
if (r, c) in self.mines:
adjacent_mines += 1
return adjacent_mines
def show_game_over(self, message):
"""显示游戏结束的消息"""
for r in range(self.height):
for c in range(self.width):
if (r, c) in self.mines:
self.buttons[r][c].config(text="💣", bg="red")
else:
self.buttons[r][c].config(state=tk.DISABLED)
self.canvas.create_text(self.width*15, self.height*15, text=message, font=("Arial", 20), fill="black")
if __name__ == "__main__":
root = tk.Tk()
game = Minesweeper(root, width=10, height=10, num_mines=20)
root.mainloop()
Traceback (most recent call last):
File "C:UsersxiangDesktopMinesweeper.py", line 90, in
game = Minesweeper(root, width=10, height=10, num_mines=20)
File "C:UsersxiangDesktopMinesweeper.py", line 21, in init
self.create_grid()
File "C:UsersxiangDesktopMinesweeper.py", line 30, in create_grid
button.grid(row=row, column=col)
File "C:UsersxiangAppDataLocalProgramsPythonPython312Libtkinter_init_.py", line 2569, in grid_configure
self.tk.call(
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack这个错误发生是因为在Tkinter中,你不能同时使用pack和grid布局管理器。你要么使用pack()来管理控件的位置,要么使用grid()来管理。
import tkinter as tk
from tkinter import messagebox
import random
class Minesweeper:
def __init__(self, master, size=10, mines=10):
self.master = master
self.size = size
self.mines = mines
self.board = [[0] * size for _ in range(size)]
self.buttons = [[None] * size for _ in range(size)]
self.revealed = [[False] * size for _ in range(size)]
self.flags = [[False] * size for _ in range(size)]
self.game_over = False
self.create_widgets()
self.place_mines()
self.calculate_numbers()
def create_widgets(self):
for row in range(self.size):
for col in range(self.size):
button = tk.Button(self.master, width=2, height=1,
command=lambda r=row, c=col: self.reveal(r, c))
button.bind('', lambda e, r=row, c=col: self.toggle_flag(r, c))
button.grid(row=row, column=col)
self.buttons[row][col] = button
def place_mines(self):
count = 0
while count < self.mines:
row = random.randint(0, self.size - 1)
col = random.randint(0, self.size - 1)
if self.board[row][col] != 'M':
self.board[row][col] = 'M'
count += 1
def calculate_numbers(self):
for row in range(self.size):
for col in range(self.size):
if self.board[row][col] == 'M':
continue
mines_count = 0
for dr in [-1, 0, 1]:
for dc in [-1, 0, 1]:
if 0 <= row + dr < self.size and 0 <= col + dc < self.size:
if self.board[row + dr][col + dc] == 'M':
mines_count += 1
self.board[row][col] = mines_count
def reveal(self, row, col):
if self.game_over or self.flags[row][col] or self.revealed[row][col]:
return
self.revealed[row][col] = True
if self.board[row][col] == 'M':
self.buttons[row][col].config(text='M', bg='red')
self.game_over = True
messagebox.showinfo("游戏结束", "你踩到地雷了!")
return
self.buttons[row][col].config(text=str(self.board[row][col]), relief=tk.SUNKEN)
if self.board[row][col] == 0:
for dr in [-1, 0, 1]:
for dc in [-1, 0, 1]:
if 0 <= row + dr < self.size and 0 <= col + dc < self.size:
if not self.revealed[row + dr][col + dc]:
self.reveal(row + dr, col + dc)
if self.check_win():
self.game_over = True
messagebox.showinfo("胜利", "恭喜,你赢了!")
def toggle_flag(self, row, col):
if self.game_over or self.revealed[row][col]:
return
if self.flags[row][col]:
self.buttons[row][col].config(text='', bg='SystemButtonFace')
self.flags[row][col] = False
else:
self.buttons[row][col].config(text='F', bg='yellow')
self.flags[row][col] = True
def check_win(self):
for row in range(self.size):
for col in range(self.size):
if self.board[row][col] != 'M' and not self.revealed[row][col]:
return False
return True
if __name__ == "__main__":
root = tk.Tk()
root.title("扫雷游戏")
game = Minesweeper(root, size=10, mines=10)
root.mainloop()