【问题标题】:Simple Tictactoe program简单的 Tictactoe 程序
【发布时间】:2016-06-19 14:17:57
【问题描述】:

我正在尝试实现一个简单的井字游戏程序,但在实现游戏时遇到了困难。这是我到目前为止的代码:

from Tkinter import *
click = False

class Buttons(object):

    def __init__(self,master):
        frame = Frame(master)
        frame.pack()

        self.button1= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button1.grid(row=0,column=0)

        self.button2= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button2.grid(row=0,column=1)

        self.button3= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button3.grid(row=0,column=2)

        self.button4= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button4.grid(row=1,column=0)

        self.button5= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button5.grid(row=1,column=1)

        self.button6= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button6.grid(row=1,column=2)

        self.button7= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button7.grid(row=2,column=0)

        self.button8= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button8.grid(row=2,column=1)

        self.button9= Button(frame,text=" ",height=4,width=8,
                             command=self.moveYes)
        self.button9.grid(row=2,column=2)

    def moveYes(self):
        global click
        global buttons
        if buttons["text"] == " " and click == False:
            buttons["text"]="X"
            click= True
        elif buttons["text"] == " " and click == True:
            buttons["text"]="O"

root = Tk()
b=Buttons(root)

root.mainloop()

当我运行它时,它会说:

global name 'buttons' is not defined

我猜我的第二种方法不正确。我不明白如何访问按钮和比较值以便更改文本。

我现在应该从双人模式开始,然后再转向人工智能吗?

【问题讨论】:

  • 如何声明一个全局变量buttons,就像使用click 一样?
  • @schwobaseggl 我试过了,但这也无济于事。 :( 可能是我使用单个变量访问单个按钮的方式是错误的吗?
  • @momo 名称buttons 未在moveYes 函数之外定义。这就是您看到该错误的原因。通常,global 用于使变量在函数内部 可访问,尽管它最初是在该函数外部 定义的。顺便提一句。您可以通过在两个 for 循环中定义按钮来减少代码重复。

标签: python python-2.7 tkinter tic-tac-toe


【解决方案1】:

首先,每当你发现自己在重复几乎相同的一行或多行代码时,这就是你需要编写某种循环的线索。

其次,您可以通过将数据作为参数传递给您的 command 函数来避免使用全局变量——这将使您得到的错误消失。

在这种情况下,它只是被单击的按钮,可以通过创建一个简短的lamdba 函数来完成,该函数将按钮作为默认参数。这必须在创建 Tkinter Button 之后进行,因此需要在创建之后进行单独的 config() 调用。像这样传递额外数据有时称为the extra arguments trick,并且可以扩展到包括其他感兴趣的项目,例如按钮的行和列(甚至它们的整个列表)。

from Tkinter import *

class Buttons(object):
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.buttons = []
        for row in xrange(3):
            for col in xrange(3):
                button = Button(frame, text=" ", height=4, width=8)
                button.config(command=lambda b=button: self.clicked(b))
                button.grid(row=row, column=col)
                self.buttons.append(button)

    def clicked(self, button):
        if button["text"] == " ":
            button["text"] = "X"
        else:
            button["text"] = "O"

root = Tk()
b = Buttons(root)
root.mainloop()

现在基本的图形用户界面正在运行,并且每当用户单击网格位置时都会调用一个函数,您可以开始实现“游戏”。这可以通过将代码添加到 clicked() 方法来完成,该方法检查哪些位置填充了哪些字符("X""O")并做出相应的响应。

我认为首先实现“AI”版本是最简单的,因为这样做需要的工作量最少。

【讨论】:

  • 感谢您的详细回复!非常有帮助:)
  • 不客气。我在答案中添加了更多建议。首先实现 AI 版本的另一个优点是,它需要您编写代码,而不是在两个播放器版本中重用,并在处理可能更复杂的版本之前提高您的 Python 和 Tkinter 技能。为了使代码更具可重用性,请尽量避免使用全局变量,并通过参数将尽可能多的数据传递给“帮助”函数,这些函数不关心玩家的类型(人类与计算机或人类与人类)。
【解决方案2】:

我认为问题在于您试图将函数中的 global 关键字分配给不存在的变量。

文件主体中没有buttons 变量。

【讨论】:

  • 变化不大。它现在说“名称'按钮'未定义”。
  • 我没有仔细查看您的其余代码 - 您就收到的一条特定错误消息提出了一个特定问题,我试图回答。无法判断是什么导致了新的错误消息,因为我不知道您刚才对代码进行了哪些更改。此外,这会改变你原来的问题,不确定你想用它去哪里。 (Stackoverflow 不适合在您编程时进行连续的来回操作。)
  • 无论如何,您似乎已经在尝试访问buttons 甚至更早,所以这可能就是您现在获得name 'buttons' not defined 的原因。您必须在每个函数的开头引用全局变量。 (或者把它移到你的班级里面。)
【解决方案3】:

当你点击一个按钮时的问题,程序需要知道你点击了哪个按钮,这就是为什么你试图访问一些全局buttons,没有必要,你可以传递按钮和任何东西您的命令处理程序中需要的其他内容,例如command=lambda self.click(self.button_x)

    self.button1= Button(frame,                                                    
                         height=4, width=8,
                         text=' ',
                         command=lambda: self.click(self.button1)
    )       

这是我在上面的按钮命令中使用的click()方法

def click(self, button):
    """
    Dummy logic for demo, it toggles between O and X
    """

    if button['text'] == ' ' or button['text'] == 'O':                 
        button['text'] = 'X'                                                
    else:                                                                   
        button['text'] = 'O'  

我已经运行了程序,它的工作原理是按钮可以在 X 和 O 之间切换,它演示了按钮命令工具,我将把实际的井字游戏留给你。强>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-12
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多