<p>这里的问题是每次调用<code>XsorOs</code>方法时都会创建<code>XorO</code>对象。这意味着<code>XsorOs.turn</code>总是1。
一种方法是从外部跟踪<code>turn</code>,并用<code>global</code>调用它,但是
当然<a href="https://docs.python.org/3/reference/simple_stmts.html?highlight=global#global" rel="nofollow noreferrer">global</a>是一个应该避免的东西,尤其是它可能会变得非常混乱。
我建议在Tk单独的“logic”类的一个子类中跟踪<code>turn</code></p>
<p>我给你举了一个例子:</p>
<p>(请注意,这个例子非常草率(特别是变量命名),应该只是告诉你我的意思)</p>
<pre><code># 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()
</code></pre>
<p><strong>编辑:</strong></p>
<ul>
<li><p><code>lambda</code>基本上是一种创建单行函数的方法。在本例中,我使用它通过事件函数传递参数。因为在内部某处<code>tkinter</code>做了类似于<code>if that mouseclick happens do passed_function(event)</code>的事情,所以你没有机会使用你自己的论点。这就是<code>lambda</code>在这里有用的原因</p></li>
<li><p><code>__init__</code>在这里可能没有那么重要,因为我以前看到人们在类主体中放置变量,显然它工作得很好,但我个人更喜欢它在构造函数中创建类的所有变量</p></li>
<li><p><code>self</code>在其他语言中类似于<code>this</code>对类或该类的对象的引用(实际上可以通过命名第一个构造函数参数来命名它,但是<code>self</code>是常用的)。它“拉”类范围内的变量,而不是函数。这意味着变量存在并且只要对象存在就可以被操纵。函数在执行后基本上会丢失所有内容。这是您以前的代码中的主要问题</p></li>
</ul>