簡體   English   中英

Python Tkinter銷毀所選按鈕旁邊的所有具有相同文本的按鈕

[英]Python Tkinter destroying all Buttons next to chosen one with same text

我想在 python 中重新創建掃雷,我試圖重新創建游戲中如果玩家選擇一個沒有任何東西的瓷磚(在我的代碼中,一個有 0 的瓷磚)它會顯示所有靠近的瓷磚它不是地雷(在我的代碼中,一個帶有 X 的圖塊)。 我曾多次嘗試這樣做,但沒有任何效果。 它將寫在 autoShow(i, j) 函數中。

任何人都可以幫忙(任何其他建議將不勝感激)?

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):
    pass

def show(i, j):
    global gameOver
    if gameOver:
        return
    firstT(i, j)
    if labels[i][j]["text"] == "0":
        autoShow(i, j)
    elif labels[i][j]["text"] == "X":
        messagebox.showinfo("Lose!", "You Lose")
        game.focus_force()
        gameOver = True
    else:
        grid[i][j].destroy()

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)]

diff(1)

您必須使用遞歸來運行show(i-1, j)等。

因為我在沒有單擊按鈕的情況下運行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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM