摆脱游戏获胜后无法按下按钮的问题

问题描述 投票:0回答:1
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import font as tkFont

# Global variable to keep track of the game board
board = [['' for _ in range(3)] for _ in range(3)]

#defines the function to switch to the game screen
def play_game():

    #creates a top level window (appears above all other windows when pressed)
    game_window = tk.Toplevel(win)

    #sets the name of the new window to "Tic-Tac-Toe Game"
    game_window.title("Tic-Tac-Toe Game")

    #sets the size of the game window when opened to 600x600
    game_window.geometry("600x600")

    #doesn't allow the main game window to be resized
    game_window.resizable(False, False)


    #creates a canvas to draw lines
    canvas = tk.Canvas(game_window, width=600, height=600)
    canvas.pack()

    #creates horizontal lines
    for i in range(1, 3):
        canvas.create_line(0, i * 200, 600, i * 200, fill="black")

    #creates vertical lines
    for i in range(1, 3):
        canvas.create_line(i * 200, 0, i * 200, 600, fill="black")


    #creates the buttons in the game window, uses configure to later destroy the button after it has been pressed
    for i in range(3):
        for j in range(3):
            x1 = i * 200
            y1 = j * 200
            button_tile = ttk.Button(game_window)
            button_tile.place(x=x1, y=y1, width=200, height=200)
            button_tile.configure(command=lambda row=i, col=j, btn=button_tile, parent=game_window: button_click(row, col, btn, parent))


#sets first turn of player to 'O' and next is 'X', so on and on
o_Turn = True



#defines the function what happens when one of the 9 buttons are pressed
def button_click(row, col, button, parent):

    #sets a global variable o_Turn so that it can be accessed anywhere - removing localerror
    global o_Turn

    #make the boolean variable an X or an O
    Sign = 'X'
    
    if o_Turn:
        Sign = 'O'

    #boolean variable to keep track of whos turn it is, and switch between X/O
    o_Turn = not o_Turn

    #creates a label that writes the player's sign onto each button after it is pressed 'text=Sign'
    ttk.Label(parent, text=Sign, font=('Times', 60, tkFont.BOLD)).place(x=(row*200)+75, y=(col*200)+55)

    # Update the game board
    board[row][col] = Sign

    #destroys the button after it has been pressed
    button.destroy()

    # Check if there's a winner
    if check_winner(Sign):
        # Open a window to display the winner
        winner_window = tk.Toplevel(parent)
        winner_window.title("Winner")
        winner_label = ttk.Label(winner_window, text=f"Player {Sign} wins!", font=('Times New Roman', 20))
        winner_label.pack(padx=20, pady=20)



def check_winner(player):
    # Check rows
    for i in range(3):
        if board[i][0] == board[i][1] == board[i][2] == player:
            return True
        

    # Check columns
    for j in range(3):
        if board[0][j] == board[1][j] == board[2][j] == player:
            return True

    # Check diagonals
    if board[0][0] == board[1][1] == board[2][2] == player:
        return True
    if board[0][2] == board[1][1] == board[2][0] == player:
        return True

    return False


#defines the function to open the user guide

def open_user_guide():
    #creates a top level window (appears above all other windows when pressed)
    guide_window = tk.Toplevel(win)

    #sets the name of the new window to "Tic-Tac-Toe Game"
    guide_window.title("User Guide")

    #sets the size of the game window when opened to 600x700
    guide_window.geometry("800x300")

    #doesn't allow the user guide window to be resized
    guide_window.resizable(False, False)

    #creates a frame to contain the labels
    frame = ttk.Frame(guide_window)
    frame.pack(expand=True, fill='both', padx=20, pady=20)

    #creates a new label with the text "How to play:" on the top of the window
    guide_label = ttk.Label(frame, text="User Guide", font=('Times New Roman', 20, 'bold'))
    guide_label.pack(pady=(0, 10), anchor='center')  #centres the label horizontally

    #creates a new text section 
    instructions_label = ttk.Label(frame, text="""
    Hi there! And welcome to my Tic Tac Toe game, made with tkinter.
    
    Here's how to play Tic-Tac-Toe! As you can see, the game is played on a grid that is 3 squares by 3 squares.

    1. The player that starts is X, and the other person is O. You and another player take turns placing X or O into a square.
    2. The first player to get all 3 marks in a row (horizontally, vertically or diagonally) wins the game.
    3. When all the squares are filled and no one has won, the game ends in a tie. AND THAT'S IT! Have fun playing!

    And press reset to play again!""",
    font=('Times New Roman', 12))
    instructions_label.pack(anchor='w')


win = tk.Tk()

#sets window size to 1000 x 600
win.geometry("1000x600")


#sets background image to a tictac
bg = tk.PhotoImage(file = "tictac.png")

#shows image using a label
backgroundimage = tk.Label(win, image=bg) 
backgroundimage.place(x = 0, y = 0)


#sets minimum window resizable size to 500 x 300
win.minsize(500, 300)

#doesn't allow the launcher window to be resized
win.resizable(False, False)

#sets title name of window to Tic-Tac-Toe (name of game)
win.title("Tic-Tac-Toe")

#integrates a new font into tkinter application
tmrn = tkFont.Font(family='Times New Roman', size=15, weight='bold')

#creates a custom style for buttons
style = ttk.Style()
style.configure('tmrn.TButton', font=('Times New Roman', 15, 'bold'), padding=(200, 10))  # Increase left and right padding to make the buttons longer


#creates a label with big black letters at the top of the window
title_label = ttk.Label(win, text="Tic-Tac-Toe Game!", font=('Times New Roman', 40, 'bold'), foreground='black')
title_label.pack(side=tk.TOP, pady=20)  # Add some padding at the top


#creates a button called 'Play' - takes the user to the actual playable game
play_button = ttk.Button(win, text="Play", command=play_game, style='tmrn.TButton')
play_button.place(relx=0.5, rely=0.6, anchor=tk.CENTER)  #positions the button just below the center

#creates a button called 'User Guide' - supposed to take the user to another window with how to play
guide_button = ttk.Button(win, text="User Guide", command=open_user_guide, style='tmrn.TButton')
guide_button.place(relx=0.5, rely=0.7, anchor=tk.CENTER)  #positions the button just below the "Play" button with some padding


win.mainloop()

这是我到目前为止的代码,当我运行它并玩井字棋游戏时,它运行良好。然而,当我完成一场获胜者的游戏并且弹出新窗口并显示“玩家 X”或“玩家 o”获胜后,我仍然可以按下按钮 - 我希望这样按钮就不能被按下不再按下,但我不确定如何 - 我知道 Button.destroy() 函数可能会起作用,但我不知道如何为剩下的几个函数执行此操作。如果我能在这方面得到一些帮助那就太好了!谢谢。

python tkinter tic-tac-toe
1个回答
0
投票

您可以引入一个全局变量,比如说game_active,来跟踪游戏是否正在进行。当游戏开始时这将为 True,当有人获胜或平局时应设置为 False。

我修改了button_click函数来检查game_active的状态,然后再继续其逻辑。如果 game_active 为 False,该函数应立即返回。

当有获胜者时,在 check_winner 函数中将 game_active 设置为 False。

显然每次新游戏开始时都将 game_active 重置为 True。

示例:

game_active = True

def button_click(行、列、按钮、父项): 全局 o_Turn,game_active

# Return immediately if the game is no longer active
if not game_active:
    return

Sign = 'X' if not o_Turn else 'O'
o_Turn = not o_Turn

ttk.Label(parent, text=Sign, font=('Times', 60, tkFont.BOLD)).place(x=(row*200)+75, y=(col*200)+55)

board[row][col] = Sign
button.destroy()

if check_winner(Sign):
    game_active = False
    winner_window = tk.Toplevel(parent)
    winner_window.title("Winner")
    ttk.Label(winner_window, text=f"Player {Sign} wins!", font=('Times New Roman', 20)).pack(padx=20, pady=20)
© www.soinside.com 2019 - 2024. All rights reserved.