2016-05-24 6 views
-1

Я разработал несколько ИИ для игры 2048. Я хотел бы показать состояние игры после каждого движения, которое делает ИИ. Для этого я создал графический интерфейс с использованием Tkinter. Первый раз, используя Tkinter, и, как видно из названия, мне кажется, что мой метод updateDisplay блокирует вызов mainloop(). Любая помощь будет оценена по достоинству.
Когда я удалю звонок до self.after(1000, self.updateDisplay(ai, game)), отобразится GUI. Тем не менее, это будет явно не обновлятьTkinter mainloop() не работает - Python

class GameGrid(Frame): 
    def __init__(self,ai, game): 
     Frame.__init__(self) 
     self.game = game 
     self.ai = ai 
     self.grid() 
     self.master.title('2048') 

     #self.gamelogic = gamelogic 

     self.grid_cells = [] 
     self.init_grid() 
     self.update_grid_cells() 
     self.after(1000, self.updateDisplay(ai, game)) 
     self.mainloop() 


    def updateDisplay(self, ai, game): 
     game.move(ai.nextMove(4)) 
     print "hello" 
     for i in range(GRID_LEN): 
      for j in range(GRID_LEN): 
       new_number = int(game.state[i][j]) 
       if new_number == 0: 
        self.grid_cells[i][j].configure(text="", bg=BACKGROUND_COLOR_CELL_EMPTY) 
       else: 
        self.grid_cells[i][j].configure(text=str(new_number), bg=BACKGROUND_COLOR_DICT[new_number], fg=CELL_COLOR_DICT[new_number]) 
     if game.over: 
      if game.won: 
       print 'You Won!' 
      else: 
       print 'Game Over :(Score:', game.score 
      return 0 
     else: 
      print "test" 
      self.after(10000, self.updateDisplay(ai, game))    



if __name__ == "__main__": 
    game = Game() 
    ai = AlphaBetaRecursive(game) 
    gui = GameGrid(ai, game) 
+0

обзванивать [ 'update_idletasks()'] (http://infohost.nmt.edu/tcc/help/pubs/ tkinter/web/universal.html) периодически где-нибудь в 'updateDisplay()' может помочь. Неясно, где функция обновления тратит большую часть своего времени на основании того, что вы опубликовали до сих пор. – martineau

+0

@martineau Спасибо за ответ. Я не размещал весь код, пытаясь сохранить его простым. 'updateDisplay()' немедленно делает ход, печатает 'hello' и' test', затем снова вызывает себя, казалось бы, не дожидаясь какого-либо периода времени вообще – user3636636

+0

Вы знаете, что у вас есть 10-секундная задержка, закодированная в 'after () 'вызов в функции' updateDisplay', правильно? Также правильным было бы назвать 'self.after (1000, self.updateDisplay, self.ai, self.game)' - иначе вы вызываете его прямо в 'after()' самом себе. – martineau

ответ

2

Когда вы self.after(1000, self.updateDisplay(ai, game)), вы звоните self.updateDisplay сразу, а не передавая функцию в качестве аргумента after. Вам нужно избавиться от внутренних круглых скобок! Согласно документам, after действительно принимает дополнительные *args, но на самом деле он не говорит, что с ними сделано (может быть, они переданы на обратный вызов? Я не уверен). Поскольку ai и game уже являются атрибутами self, вам фактически не нужно передавать их как аргументы вообще. Просто используйте:

self.after(1000, self.updateDisplay) 

И изменить определение updateDisplay к:

def updateDisplay(self): 
    # use self.ai and self.game rather than ai and game in the implementation of the function 
    ... 
+0

Спасибо! Это сработало. Я потратил некоторое время, пытаясь понять это. Еще раз спасибо – user3636636

+1

Дополнительные аргументы передаются на обратный вызов. Совершенно безопасно делать 'self.after (1000, self.updateDisplay, ai, game)', хотя нет смысла передавать атрибуты объектов между методами одного и того же класса. –

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