井字游戏项目快要完成了,我在绑定和添加平局条件方面遇到了一些问题。我能够将函数绑定到,并且它们可以正常工作,但是我希望将它们绑定到R和转义键(将reset_game绑定到R并接近转义)。我也尝试过为平局条件添加变量k,但该变量k尚未定义。这是代码:
from tkinter import *
import tkinter.messagebox
ttt = Tk()
ttt.title("Tic Tac Toe")
w = Canvas(ttt, width = 902, height = 902)
w.configure (bg = "white")
w.pack()
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
size = 300
player = 1
w.create_line(0, 300, 902, 300, fill = "black")
w.create_line(0, 601, 902, 601, fill = "black")
w.create_line(300, 0, 300, 902, fill = "black")
w.create_line(601, 0, 601, 902, fill = "black")
def on_click(event):
global m
global player
global k
row = event.y // size
col = event.x // size
if m[row][col] == 0:
cx = col * size + size // 2
cy = row * size + size // 2
if player == 1:
draw_X(cx, cy)
print ("Player 1, X")
else:
draw_O(cx, cy)
print ("Player 2, O")
m[row][col] = player
Win()
player = 2 if player == 1 else 1
k = k + 1
def draw_O(x, y):
radius = size // 3
w.create_oval(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell')
def draw_X(x, y):
radius = size // 3
w.create_line(x-radius, y-radius, x+radius, y+radius, width=5, tag='cell')
w.create_line(x+radius, y-radius, x-radius, y+radius, width=5, tag='cell')
def reset_game(event):
global m
global player
w.delete('cell')
m = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
player = 1
k = 0
def tie():
if (k==8):
tkinter.messagebox.showinfo("Tic Tac Toe", "Tie")
def Win():
if (m[0][0] == m[0][1] and m[0][0] == m[0][2] and m[0][0]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][0]))
ttt.destroy()
print ("Player", str(m[0][0]), "wins")
elif (m[0][0] == m[1][0] and m[0][0] == m[2][0] and m[0][0]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][0]))
ttt.destroy()
print ("Player", str(m[0][0]), "wins")
elif (m[1][0] == m[1][1] and m[1][0] == m[1][2] and m[1][0]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[1][0]))
ttt.destroy()
print ("Player", str(m[1][0]), "wins")
elif (m[0][1] == m[1][1] and m[0][1] == m[2][1] and m[0][1]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][1]))
ttt.destroy()
print ("Player", str(m[0][1]), "wins")
elif (m[0][2] == m[1][2] and m[0][2] == m[2][2] and m[0][2]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][2]))
ttt.destroy()
print ("Player", str(m[0][2]), "wins")
elif (m[2][0] == m[2][1] and m[2][0] == m[2][2] and m[2][0]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[2][0]))
ttt.destroy()
print ("Player", str(m[2][0]), "wins")
elif (m[0][0] == m[1][1] and m[0][0] == m[2][2] and m[0][0]!=0):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][0]))
ttt.destroy()
print ("Player", str(m[0][0]), "wins")
elif (m[0][2] == m[1][1] and m[0][2] == m[2][0] and m[0][2]):
tkinter.messagebox.showinfo("Tic Tac Toe", "Winner is player " + str(m[0][2]))
ttt.destroy()
print ("Player", str(m[0][2]), "wins")
w.bind('<Button-1>', on_click)
def close(event):
ttt.destroy()
w.bind('<Button-2>',close)
w.bind('<Button-3>', reset_game)
ttt.mainloop()
我也想在某人获胜或没有平局的情况下平局以停止比赛,以便我重新设置。关于如何做到这一点的任何想法?
由于您已经添加了全局变量k
作为玩转数,因此player
可以由k
的值确定,因此可以将其从全局变量中删除。
您需要声明全局变量k
:
m = [[0,0,0], [0,0,0], [0,0,0]]
size = 300
k = 0
此外,您可以简化/修改函数Win
以接受row
和col
作为参数并返回是否有赢家:
def Win(row, col):
# check horizontal
if m[row][0] == m[row][1] == m[row][2]:
return m[row][col]
# check vertical
if m[0][col] == m[1][col] == m[2][col]:
return m[row][col]
# check diagonals
cell = (row, col)
if cell in ((0,0), (1,1), (2,2)) and m[0][0] == m[1][1] == m[2][2]:
return m[row][col]
if cell in ((2,0), (1,1), (0,2)) and m[2][0] == m[1][1] == m[0][2]:
return m[row][col]
# no winner, returns None
return None
然后修改on_click
功能:
def on_click(event):
global m
global k
row = event.y // size
col = event.x // size
if m[row][col] == 0:
cx = col * size + size // 2
cy = row * size + size // 2
# determine current player
player = 1 + k % 2
if player == 1:
draw_X(cx, cy)
print("Player 1, X")
else:
draw_O(cx, cy)
print("Player 2, O")
m[row][col] = player
k += 1
# only need to check winner after 5 turns
if k >= 5:
winner = Win(row, col)
msg = None
if winner:
msg = "Winner is player {}: {}".format(player, 'X' if player == 1 else 'O')
elif k == 9:
msg = "Tie game"
if msg:
tkinter.messagebox.showinfo("Tic Tac Toe", msg)
reset_game()
对于键绑定:
w.bind('<Escape>', lambda e: ttt.destroy())
w.bind('R', reset_game)
w.bind('r', reset_game)
w.focus_set() # Canvas need to get the focus in order to get the keyboard events