Программа Tkinter не работает правильно с первой попытки, работает как задумано после перезапуска - PullRequest
0 голосов
/ 07 декабря 2018

Плитки с графическим интерфейсом в этой программе не работают должным образом при первом запуске программы, но, кажется, они работают нормально после нажатия кнопки перезагрузки.Кажется, проблема в том, что find_closest() не выбирает правильные квадраты при запуске, но после перезапуска в методе play() он работает правильно.

def play(self, event):
    """
    user performs a move
    calls computer move directly after if game not over
    """
    selected_square = self.canvas.find_closest(event.x, event.y)

Я пытался переместить boardбыть переменной экземпляра, но это не исправило ее.

Вот метод __init__:

class Game(object):
'''
GUI Tic-tac-toe game.

Argument:
parent (tkinter.Tk): the root window object

Attributes:
canvas = (tkinter.Canvas) widget defining game board
game_over = (bool) game state, game over = False, game ongoing = True
moves = (int) number of moves taken by both user and computer
label = (tkinter.Label) shows win/loss/draw message
'''

# Add your class variables if needed here - square size, etc...)
board = [[0, 0, 0],
         [0, 0, 0],
         [0, 0, 0]]

MAX_MOVES = 9

def __init__(self, parent):
    self.parent = parent
    parent.title('Tic Tac Toe')
    # Create the restart button widget
    restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
                                    command=self.restart)
    restart_button.pack()
    # Create a canvas widget

    self.canvas = tkinter.Canvas(parent, background='white', width=300,
                                 height=300)

    self.canvas.create_rectangle(0, 0, 300, 300)
    self.canvas.create_rectangle(0, 0, 100, 100)
    self.canvas.create_rectangle(100, 0, 200, 100)
    self.canvas.create_rectangle(200, 0, 300, 100)

    self.canvas.create_rectangle(0, 100, 100, 200)
    self.canvas.create_rectangle(100, 100, 200, 200)
    self.canvas.create_rectangle(200, 100, 300, 200)

    self.canvas.create_rectangle(0, 200, 100, 300)
    self.canvas.create_rectangle(100, 200, 200, 300)
    self.canvas.create_rectangle(200, 200, 300, 300)

    self.canvas.pack()

    self.label = tkinter.Label(self.parent, text="")
    self.label.pack()

    self.game_over = False
    if not self.game_over:
        self.canvas.bind("<Button-1>", self.play)
    self.moves = 0

Вот метод перезапуска:

    def restart(self):
    """
    resets game to beginning state

    label erased, game tiles turned back white, button-1 rebound, moves set
    to zero
    """
    for square in self.canvas.find_all():
        self.canvas.itemconfigure(square, fill='white')
    self.board = [[0, 0, 0],
                  [0, 0, 0],
                  [0, 0, 0]]
    self.moves = 0
    self.game_over = False
    self.canvas.bind("<Button-1>", self.play)
    self.label.config(text="")

Остальной код можно найти здесь .

Я попытался напечатать event.x и event.y, и похоже, что они регистрируются правильно, а также обновляютдоска правильно.

1 Ответ

0 голосов
/ 07 декабря 2018

Холст / привязки не настроены должным образом при запуске игры.Я на самом деле не копался в вашем коде, чтобы выяснить причину (есть много, чтобы покопаться для краткого ответа), но ваши индексы, похоже, отстают при первом запуске.Это можно исправить, добавив цикл настройки холста из функции restart() в игровой цикл в нижней части блока кода следующим образом:

def main():
    root = tkinter.Tk()
    gen_game = Game(root)
    **for square in gen_game.canvas.find_all():**
        **gen_game.canvas.itemconfigure(square, fill='white')**
    root.mainloop()

или добавив его в конец __init__ действует следующим образом:

def __init__(self, parent):
    self.parent = parent
    parent.title('Tic Tac Toe')


    # Create the restart button widget
    restart_button = tkinter.Button(self.parent, text='RESTART', width=20,
                                    command=self.restart)
    restart_button.pack()
    # Create a canvas widget

    self.canvas = tkinter.Canvas(parent, background='white', width=300,
                                 height=300)

    self.canvas.create_rectangle(0, 0, 300, 300)
    self.canvas.create_rectangle(0, 0, 100, 100)
    self.canvas.create_rectangle(100, 0, 200, 100)
    self.canvas.create_rectangle(200, 0, 300, 100)

    self.canvas.create_rectangle(0, 100, 100, 200)
    self.canvas.create_rectangle(100, 100, 200, 200)
    self.canvas.create_rectangle(200, 100, 300, 200)

    self.canvas.create_rectangle(0, 200, 100, 300)
    self.canvas.create_rectangle(100, 200, 200, 300)
    self.canvas.create_rectangle(200, 200, 300, 300)

    self.canvas.pack()

    self.label = tkinter.Label(self.parent, text="")
    self.label.pack()

    self.game_over = False
    if not self.game_over:
        self.canvas.bind("<Button-1>", self.play)
    self.moves = 0

    **for square in self.canvas.find_all():**
        **self.canvas.itemconfigure(square, fill='white')**

Примечание. На самом деле не включайте ** при копировании кода.Это просто для акцента.Если бы это не был блок кода, он был бы переформатирован как жирный, но его нельзя отформатировать как полужирный и code.

...