2016-06-19 4 views
0

Я пытаюсь реализовать простую программу tic tac toe, но с трудностями при реализации игр. Это код, который я до сих пор:Простая программа Tictactoe

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 

Я предполагаю, что мой второй метод не является правильным. Я не понимаю, как получить доступ к кнопкам и сравнить значения, чтобы я мог изменить текст.

Должен ли я, на данный момент, начать с формата двойного игрока, а затем перейти к AI?

+1

Как насчет того, что вы объявляете глобальную переменную 'buttons', как вы делаете с' click'? – schwobaseggl

+0

@schwobaseggl я пытался, но это тоже не помогает. :(может ли быть так, что мой способ доступа к отдельным кнопкам с использованием одной переменной не так? – momo

+0

@momo Имя 'buttons' не определено вне функции' 'moveYes', поэтому вы видите эту ошибку. Как правило,' ' global' используется для того, чтобы сделать переменную доступной * внутри * функцией, хотя она была первоначально определена * вне * этой функции. Кстати, вы можете сократить повторение кода, указав вместо этого кнопки в двух циклах 'for'. – jDo

ответ

2

Прежде всего, всякий раз, когда вы повторяете почти ту же строку или строки кода, это ключ к необходимости писать какой-то цикл.

Во-вторых, вы можете избежать использования глобальной переменной, передав данные в качестве аргумента функции 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», потому что для этого потребуется минимальное усилие.

+0

Благодарим вас за подробный ответ! очень полезно :) – momo

+1

Добро пожаловать. Я добавил еще пару предложений к моему ответу. Другим преимуществом реализации версии AI является то, что вам потребуется написать код, который можно использовать повторно в двухпользовательской версии и улучшить свои навыки Python и Tkinter, прежде чем решать вероятную более сложную версию. Чтобы сделать код более многоразовым, старайтесь избегать использования глобальных переменных и передавать как можно больше данных с помощью аргументов в функции «помощника», которые не заботятся о том, что такое игроки (человеческие против компьютера или человека и человека). – martineau

1

Я думаю, проблема в том, что вы пытаетесь присвоить ключевое слово global внутри вашей функции переменной, которая не существует.

В основной части вашего файла нет переменной buttons.

+0

, которые didn 't меняет много, теперь он говорит, что «имя» кнопки «не определено». – momo

+0

У меня не было более пристального взгляда на остальную часть вашего кода - вы задали один конкретный вопрос об одном конкретном сообщении об ошибке, которое я попробовал ответить. Невозможно сказать, что вызывает новые сообщения об ошибках, потому что я не знаю, какие изменения вы внесли в свой код только сейчас. Кроме того, это изменило бы ваш первоначальный вопрос, не совсем уверен, куда вы пытаетесь пойти с ним . (Stackoverflow не является подходящее место для непрерывного воспроизведения назад и вперед, пока вы что-то программируете.) – Kay

+0

В любом случае, похоже, вы пытаетесь получить доступ к кнопкам даже раньше, так что, вероятно, именно поэтому вы теперь получаете «имя», кнопки «не определены». Вам нужно будет ссылаться на глобальную переменную в начале каждой функции. (Или переместите его внутри своего класса.) – Kay

0

Проблема, когда вы нажимаете кнопку, программа должна знать, какую кнопку вы нажали, поэтому вы пытаетесь получить доступ к некоторому глобальному 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, который демонстрирует средство управления кнопками, я оставлю вам настоящую игру tic tac toe.

+0

ах! Спасибо! да, я получил ошибку. – momo

Смежные вопросы