我希望X和O动画在单击鼠标时来回切换。问题出在函数XorO中。我不太清楚为什么,但是单击它只会创建X。我认为这可能与我写转弯变量的方式有关。这就是我所拥有的。
from tkinter import *
tk = Tk()
width = 600
third = width / 3
canvas = Canvas(width=width, height=width)
tk.title = ("Tic Tac Toe")
line1 = canvas.create_line(200, 0, 200, 600)
line2 = canvas.create_line(400, 0, 400, 600)
line3 = canvas.create_line(0, 200, 600, 200)
line4 = canvas.create_line(0, 400, 600, 400)
def mouse_click(event):
col = int(event.x / third)
row = int(event.y / third)
XorO(row, col)
def XorO(row,col):
class XsorOs:
turn = 1
if turn is (1 or 3 or 5 or 7 or 9):
canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)
else:
canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
turn += 1
canvas.pack()
canvas.bind("<Button-1>", mouse_click)
canvas.mainloop()
答案 0 :(得分:1)
这里的问题是,每次调用XsorOs
方法时都会创建XorO
对象。这意味着XsorOs.turn
始终为1。
一种方法是从外部跟踪turn
并使用global
进行调用,但是使用
global中的“#”是应该避免的,尤其是它可能变得非常混乱。
我建议在Tk单独的“逻辑”类的自己的子类中跟踪turn
我为您提供了后者的示例:
(请注意,此示例非常草率(尤其是变量命名),应该只显示我的意思)
# stays the same until 'line4 = canvas.create_line(0, 400, 600, 400)'
class XsorOs:
def __init__(self):
self.turn = 1
def click(self, row, col):
if self.turn is (1 or 3 or 5 or 7 or 9):
canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)
else:
canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
self.turn += 1
def mouse_click(c, event):
col = int(event.x / third)
row = int(event.y / third)
c.click(row, col)
xo = XsorOs()
canvas.pack()
canvas.bind("<Button-1>", lambda event: mouse_click(xo, event))
canvas.mainloop()
编辑:
lambda
基本上是一种创建单行函数的方法。在这种情况下,我使用它通过事件函数传递参数。由于内部tkinter
的作用类似于if that mouseclick happens do passed_function(event)
,因此您没有机会使用自己的参数。这就是lambda
在这里有用的原因
__init__
在这里可能不是那么重要,因为我看到人们之前在类主体中放置了变量,显然它可以正常工作,但是我个人更喜欢它在构造函数中创建类的所有变量。
self
就像其他语言中的this
一样,是对类或该类对象的引用(实际上,您可以通过命名第一个构造函数参数来按自己的方式命名,但是self
是常用的)。它在类的范围内而不是在函数范围内“拉”变量。这意味着变量存在,只要对象存在,就可以对其进行操作。函数基本上在执行后会丢失所有内容。那是先前代码中的主要问题。
答案 1 :(得分:-1)
根据您对代码的一些调整,我设法修复了它。但是,我可以说,如果创建了X,则不能在同一图块上创建O和X?谢谢你的帮助。到目前为止,这就是我所拥有的。
from tkinter import *
tk = Tk()
width = 600
third = width / 3
canvas = Canvas(width=width, height=width)
tk.title = "Tic Tac Toe"
line1 = canvas.create_line(200, 0, 200, 600)
line2 = canvas.create_line(400, 0, 400, 600)
line3 = canvas.create_line(0, 200, 600, 200)
line4 = canvas.create_line(0, 400, 600, 400)
class XsorOs:
def __init__(self):
self.turn = 0
self.clicked = []
def click(self, row, col):
if (row, col) not in self.clicked
if self.turn is 0:
canvas.create_line(col * third, row * third, (col + 1) * third, (row + 1) * third)
canvas.create_line((col + 1) * third, row * third, col * third, (row + 1) * third)
self.turn += 1
elif self.turn is 1:
canvas.create_oval(col * third + 5, row * third + 5, (col + 1) * third - 5, (row + 1) * third - 5)
self.turn -= 1
else:
print("Game Over")
self.clicked.append((row, col))
def mouse_click(c, event):
col = int(event.x / third)
row = int(event.y / third)
c.click(row, col)
xo = XsorOs()
canvas.pack()
canvas.bind("<Button-1>", lambda event: mouse_click(xo, event))
canvas.mainloop()
此外,如果您有理由使用我在该评论中谈论的方法,请您解释一下原因。