python扫雷小游戏2.0
2024-09-27 21:29:02
发布于:浙江
哈哈哈,感谢复仇者_零大佬的修改,现在版本的扫雷已经支持连开和插旗啦,我很高兴与大家分享!
import tkinter as tk
import random
from tkinter import messagebox
class Minesweeper:
def __init__(self, root, rows=10, cols=10, mines=10):
self.root = root
self.rows = rows
self.cols = cols
self.mines = mines
self.grid = []
self.revealed = []
self.flags = []
self.init_grid()
self.init_ui()
def init_grid(self):
self.grid = [[0 for _ in range(self.cols)] for _ in range(self.rows)]
self.revealed = [[False for _ in range(self.cols)] for _ in range(self.rows)]
self.flags = [[False for _ in range(self.cols)] for _ in range(self.rows)]
self.place_mines()
self.fill_values()
def place_mines(self):
mines_placed = 0
while mines_placed < self.mines:
r = random.randint(0, self.rows - 1)
c = random.randint(0, self.cols - 1)
if self.grid[r][c] != 'M':
self.grid[r][c] = 'M'
mines_placed += 1
def fill_values(self):
directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
for r in range(self.rows):
for c in range(self.cols):
if self.grid[r][c] == 'M':
continue
mines_count = 0
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < self.rows and 0 <= nc < self.cols and self.grid[nr][nc] == 'M':
mines_count += 1
self.grid[r][c] = mines_count
def init_ui(self):
self.root.title("扫雷游戏")
self.frames = []
for r in range(self.rows):
frame_row = []
for c in range(self.cols):
btn = tk.Button(self.root, text="", width=3, height=1)
btn.grid(row=r, column=c)
btn.bind('<Button-1>', lambda e, btn=(r, c): self.reveal(btn)) # 左键揭开
btn.bind('<Button-3>', lambda e, btn=(r, c): self.toggle_flag(btn)) # 右键插旗
frame_row.append(btn)
self.frames.append(frame_row)
def reveal(self, cell):
r, c = cell
if self.revealed[r][c] or self.flags[r][c]: # 已揭开或已插旗
return
self.revealed[r][c] = True
if self.grid[r][c] == 'M':
self.frames[r][c].config(text='*', bg='red')
self.reveal_all_mines()
self.game_over(False)
return
self.frames[r][c].config(text=self.grid[r][c])
if self.grid[r][c] == 0:
self.reveal_neighbors(r, c)
self.check_victory()
def toggle_flag(self, cell):
r, c = cell
if self.revealed[r][c]:
return # 已揭开的格子不能插旗
if self.flags[r][c]:
self.frames[r][c].config(text="") # 取消旗帜
self.flags[r][c] = False
else:
self.frames[r][c].config(text="🚩", fg="red") # 插旗
self.flags[r][c] = True
def reveal_neighbors(self, r, c):
directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < self.rows and 0 <= nc < self.cols and not self.revealed[nr][nc] and not self.flags[nr][nc]:
self.reveal((nr, nc))
def reveal_all_mines(self):
for r in range(self.rows):
for c in range(self.cols):
if self.grid[r][c] == 'M':
self.frames[r][c].config(text='*', bg='red')
def check_victory(self):
"""检查是否胜利:所有没有地雷的格子都被揭开"""
for r in range(self.rows):
for c in range(self.cols):
if self.grid[r][c] != 'M' and not self.revealed[r][c]:
return # 如果还有非地雷的格子未被揭开,继续游戏
self.game_over(True) # 如果所有非地雷格子都揭开,胜利
def game_over(self, victory):
"""游戏结束,显示胜利或失败信息,并重新开始游戏"""
if victory:
messagebox.showinfo("游戏结束", "恭喜!你赢了!")
else:
messagebox.showinfo("游戏结束", "你踩到了地雷!游戏结束。")
self.restart_game()
def restart_game(self):
"""重新开始游戏,重置所有内容"""
for r in range(self.rows):
for c in range(self.cols):
self.frames[r][c].config(text="", bg='SystemButtonFace')
self.init_grid()
def main():
root = tk.Tk()
game = Minesweeper(root, rows=10, cols=10, mines=10)
root.mainloop()
if __name__ == "__main__":
main()
全部评论 3
顶顶顶
2024-09-29 来自 浙江
1码风看着就很爽(
2024-09-27 来自 广东
0大神帮我改过了
2024-09-28 来自 浙江
0原本没这么好看,根本没封装
2024-09-28 来自 浙江
0我之前发过,你去看看帮我再改改【偷笑】
2024-09-28 来自 浙江
0
顶
2024-09-27 来自 浙江
0
有帮助,赞一个