import tkinter as tk
import tkinter.ttk as ttk
from tkinter import font as tkFont
#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")
global buttons[0][0]
global buttons[0][1]
buttons[0][0] = ttk.Button(game_window, text=" ", command=button_click, style='tmrn.TButton')
buttons[0][1] = ttk.Button(game_window, text=" ", command=button_click, style='tmrn.TButton')
#creates a 3x3 grid of buttons
buttons = [[None] * 3 for _ in range(3)] #creates a 3x3 grid of nothing so far
for i in range(3):
for j in range(3):
#calculates the coordinates for each button
x1 = j * 200
y1 = i * 200
x2 = (j + 1) * 200
y2 = (i + 1) * 200
#creates a button at position (i, j)
buttons[i][j] = ttk.Button(game_window, command=lambda row=i, col=j: button_click(row, col))
buttons[i][j].place(x=x1, y=y1, width=200, height=200)
def button_click(row, col):
print(f"Button clicked at row {row}, column {col}")
pass
#make another function which refers to button click event - draw X in that square
#create a flag for X's turn or O's turn and changes when a button is clicked
#on button press display X or O
#defines what to do when a button is clicked
#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()
#add a restart button to reset the game
这是我到目前为止的代码,我试图弄清楚如何在单击 play_game 窗口中的按钮时显示 X 和 O。例如,对于左上角的按钮,如果首先按下“buttons[0][0]”,则应显示 X,而用户按下的下一个按钮应显示 O,依此类推,但如果用户按下已经点击了一个方块,X或O的值不能改变。现在我只想在单击按钮时显示一个 X,然后显示一个 O,但我遇到了很多错误。
我尝试添加 2 个按钮作为示例,左上角和顶部中间,显示空白,它给出了本地错误,所以我尝试定义它,但我收到了更多错误。
因此,首先是您开始使用全局又名
global buttons[0][0]
&global buttons[0][1]
的错误,为了简单起见,您使用global来获取变量/函数,而不是过多地定义它,至少不在该行上定义它。它是全局范围内的变量/函数的列表。另外,您不需要像这样定义按钮:
buttons[0][0] = ttk.Button(game_window, text=" ", command=button_click, style='tmrn.TButton')
buttons[0][1] = ttk.Button(game_window, text=" ", command=button_click, style='tmrn.TButton')
因为您已经在 for 循环中执行此操作。无论如何,解决方案:
我通过命令传递按钮以稍后销毁该按钮。我还传递了父对象,并且正在使用配置,因此我可以在定义按钮后访问该按钮。
button_tile.configure(command=lambda row=i, col=j, btn=button_tile, parent=game_window: button_click(row, col, btn, parent))
我们还需要一个布尔值来跟踪转弯,还需要在 X/O 之间切换
o_Turn = not o_Turn
将布尔值变成 X 或 O:
Sign = '𝕏'
if o_Turn:
Sign = '◯'
你有看起来像这样的东西:
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))
o_Turn = True
def button_click(row, col, button, parent):
#print(f"Button clicked at row {row}, column {col}")
global o_Turn
Sign = '𝕏'
if o_Turn:
Sign = '◯'
o_Turn = not o_Turn
ttk.Label(parent, text=Sign, font=('Corbel', 50, tkFont.BOLD)).place(x=(row*200)+75, y=(col*200)+55)
button.destroy()
希望有帮助:)