class GUI(object): def __init__(self): ''' constructor of `class GUI`. The default level is 'EASY'. ''' self.app = Tk() self.app.title('Tic Tac Toe') self.app.resizable(width=False, height=False) self.board = Board() self.font = Font(family="Helvetica", size=32) self.font_levels = Font(family="Times", size=14) self.buttons = {} self.level = 'EASY' for row in range(DIMENSIONS): for col in range(DIMENSIONS): handler = lambda x=row, y=col: self.move(x, y, 'EASY') button_T = Button(self.app, command=handler, font=self.font, width=3, height=2, bd=3) button_T.grid(row=col, column=row) self.buttons[row, col] = button_T self.which_level() self.update() def which_level(self): ''' #FF6103: cadmiumorange #00CD00: green3 #EE0000: red2 ''' handler_E = lambda: self.reset('EASY') button_E = Button(self.app, text="EASY", command=handler_E, bg="#00CD00", foreground="white", font=self.font_levels, bd=4) button_E.grid(row=DIMENSIONS+1, column=0, columnspan=1, sticky="WE") handler_M = lambda: self.reset('MEDIUM') button_M = Button(self.app, text="MEDIUM", command=handler_M, bg="#FF6103", foreground="white", font=self.font_levels, bd=4) button_M.grid(row=DIMENSIONS+1, column=1, columnspan=1, sticky="WE") handler_H = lambda: self.reset('HARD') button_H = Button(self.app, text="HARD", command=handler_H, bg="#EE0000", foreground="white", font=self.font_levels, bd=4) button_H.grid(row=DIMENSIONS+1, column=2, columnspan=1, sticky="WE") def reset(self, level): ''' This function resets the `board` after any level is selected. A new instance of `Board()` is created, all the buttons are cleared and then new buttons are created. ''' self.board = Board() for button in self.app.grid_slaves(): button.grid_forget() self.create_buttons(level) self.which_level() self.update() def create_buttons(self, level): ''' This functions creates buttons according to the selected level. ''' for row in range(DIMENSIONS): for col in range(DIMENSIONS): if level == 'HARD': handler = lambda x=row, y=col: self.move(x, y, 'HARD') self.level = 'HARD' elif level == 'EASY': handler = lambda x=row, y=col: self.move(x, y, 'EASY') self.level = 'EASY' elif level == 'MEDIUM': handler = lambda x=row, y=col: self.move(x, y, 'MEDIUM') self.level = 'MEDIUM' button_T = Button(self.app, command=handler, font=self.font, width=3, height=2, bd=3) button_T.grid(row=col, column=row) self.buttons[row, col] = button_T def move(self, row, col, level): ''' inputs: `row`, `col`, `level`, where the turn is to be played. This function calls the `best_score` of a specific level depending on the level selected and location on which user plays a turn. ''' self.app.config(cursor="watch") self.app.update() self.board = self.board.play_turn(row, col) self.update() if level == 'HARD': move = self.board.best_score_hard() elif level == 'EASY': move = self.board.best_score_easy() elif level == 'MEDIUM': move = self.board.best_score_medium() if move: self.board = self.board.play_turn(move[0], move[1]) self.update() self.app.config(cursor="") def update(self): ''' input: None This function updates the board. #FF0000: red1 ''' for row in range(DIMENSIONS): for col in range(DIMENSIONS): text = self.board.grid[row][col] self.buttons[row, col]['text'] = text self.buttons[row, col]['disabledforeground'] = 'black' if text == self.board.empty_location: self.buttons[row, col]['state'] = 'normal' else: self.buttons[row, col]['state'] = 'disabled' status = self.board.won() if self.level == 'EASY': status = self.board.won_easy() if not status: status = self.board.won() if status: for (row, col) in status: self.buttons[row, col]['disabledforeground'] = '#FF0000' for (row, col) in self.buttons: self.buttons[row, col]['state'] = 'disabled' for row in range(DIMENSIONS): for col in range(DIMENSIONS): self.buttons[col, row].update() def mainloop(self): self.app.mainloop()