Вы должны использовать рекурсию для запуска show(i-1, j)
, et c.
Поскольку я запускаю show(i-1, j)
без нажатия кнопки, поэтому мне также нужно grid[i][j] = None
, чтобы узнать, существует ли кнопка.
Я не знаю, не нужны ли ей другие тесты, в которых место показано.
def autoShow(i, j):
grid[i][j].destroy()
grid[i][j] = None
if i > 0:
show(i-1, j)
if j > 0:
show(i, j-1)
if i < rows-1:
show(i+1, j)
if j < cols-1:
show(i, j+1)
if i > 0 and j > 0:
show(i-1, j-1)
if i > 0 and j < cols-1:
show(i-1, j+1)
if i < rows-1 and j < cols-1:
show(i+1, j+1)
if i < rows-1 and j > 0:
show(i+1, j-1)
def show(i, j):
global gameOver
if gameOver:
return
firstT(i, j)
# check if button still exists
if grid[i][j] is None:
return
if labels[i][j]["text"] == "0":
autoShow(i, j)
elif labels[i][j]["text"] == "X":
grid[i][j].destroy()
grid[i][j] = None
messagebox.showinfo("Lose!", "You Lose")
game.focus_force()
gameOver = True
else:
grid[i][j].destroy()
grid[i][j] = None
Полный код, который я тестировал
import tkinter as tk
from tkinter import messagebox
from random import randint
def difficulty(diff):
global rows, cols, mines, size
if diff == 1:
rows = 9
cols = 9
mines = 10
size = "341x368"
elif diff == 2:
rows = 16
cols = 16
mines = 40
size = "606x654"
else:
rows = 16
cols = 30
mines = 99
size = "1139x606"
play()
def firstT(l, m):
global firstTurn
if firstTurn:
mPos = []
firstTurn = False
for x in range(mines):
minesLoop = True
while minesLoop:
x = randint(0, rows - 1)
y = randint(0, cols - 1)
if grid_text[x][y].get() != "X":
near = False
if near == False:
mPos.append([x, y])
minesLoop = False
grid_text[x][y].set("X")
[[labels[i][j].configure(text = grid_text[i][j].get()) for j in range(cols)] for i in range(rows)]
for i in range(rows):
for j in range(cols):
nearby = 0
for ii in range(i - 1, i + 2):
for jj in range(j - 1, j + 2):
if ii >= 0 and jj >= 0 and ii < rows and jj < cols:
if labels[i][j]["text"] == "" and labels[ii][jj]["text"] == "X" and not (i, j) in mPos:
nearby += 1
if labels[i][j]["text"] != "X":
grid_text[i][j] = str(nearby)
labels[i][j].configure(text = grid_text[i][j])
def autoShow(i, j):
grid[i][j].destroy()
grid[i][j] = None
if i > 0:
show(i-1, j)
if j > 0:
show(i, j-1)
if i < rows-1:
show(i+1, j)
if j < cols-1:
show(i, j+1)
if i > 0 and j > 0:
show(i-1, j-1)
if i > 0 and j < cols-1:
show(i-1, j+1)
if i < rows-1 and j < cols-1:
show(i+1, j+1)
if i < rows-1 and j > 0:
show(i+1, j-1)
def show(i, j):
global gameOver
if gameOver:
return
firstT(i, j)
if grid[i][j] is None:
return
if labels[i][j]["text"] == "0":
autoShow(i, j)
elif labels[i][j]["text"] == "X":
grid[i][j].destroy()
grid[i][j] = None
messagebox.showinfo("Lose!", "You Lose")
game.focus_force()
gameOver = True
else:
grid[i][j].destroy()
grid[i][j] = None
def play():
global firstTurn, gameOver, game, grid, grid_text, labels
firstTurn = True
gameOver = False
game = tk.Toplevel(root)
game.title("Minesweeper")
game.geometry(size)
grid_text = [[tk.StringVar() for j in range(cols)] for i in range(rows)]
labels = [[tk.Label(game, text = grid_text[i][j].get()) for j in range(cols)] for i in range(rows)]
[[labels[i][j].grid(row = i, column = j) for j in range(cols)] for i in range(rows)]
grid = [[tk.Button(game, width = 4, height = 2, command = lambda i = i, j = j: show(i, j)) for j in range(cols)] for i in range(rows)]
[[grid[i][j].grid(row = i, column = j) for j in range(cols)] for i in range(rows)]
xoutside = [[tk.Button(game, width = 4, height = 2).grid(row = i, column = cols + 1) for j in range(cols)] for i in range(rows)]
youtside = [[tk.Button(game, width = 4, height = 2).grid(row = rows + 1, column = j) for j in range(cols)] for i in range(rows)]
root = tk.Tk()
difficulty(1)
root.mainloop()