Sean Meads
Sean Meads

Reputation: 33

Python Tkinter - How to make certain code use less memory

I am programming an Othello game in a GUI. I have begun working on the animations that flip certain tiles, which is here. My computer(s) will start choking when the when the amount of tiles on the board becomes larger. I do not know what to do to simplify this code or use less memory. (I can use an automove key I have enabled to finish the game at light speed, without the animations. That works fine.) Here is the definition I am using to flip the tiles.

    def animateFlips(self, i):
    self._canvas.delete(tkinter.ALL)
    column_width = self._canvas.winfo_width()/Othello.COLUMNS
    row_height = (self._canvas.winfo_height()-self._scoreBoard)/Othello.ROWS
    newBoard = self._game.board
    animatedTileCoords = []
    color = ''
    oppcolor = ''
    if self._game.turn == 2:
        color = 'black'
        oppcolor = 'white'
    elif self._game.turn == 1:
        color = 'white'
        oppcolor = 'black'
    for x in range(Othello.COLUMNS):
        for y in range(Othello.ROWS):
            x1 = x * column_width
            y1 = y * row_height
            x2 = x1 + column_width
            y2 = y1 + row_height
            self._canvas.create_rectangle(x1,y1,x2,y2)
            if self._game.board[x][y] == 1:
                self._canvas.create_oval(x1,y1,x2,y2,fill='black')
            elif self._game.board[x][y] == 2:
                self._canvas.create_oval(x1,y1,x2,y2,fill='white')
            elif self._game.board[x][y] == 3 or self._game.board[x][y] == 4:
                animatedTileCoords.append([x,y])
    for x, y in animatedTileCoords:
        x1 = x * column_width
        y1 = y * row_height
        x2 = x1 + column_width
        y2 = y1 + row_height
        if i == 1:
            self._canvas.create_oval(x1,y1,x2,y2,fill=oppcolor)
            self._canvas.after(50, lambda: self.animateFlips(2))
        elif i == 2:
            self._canvas.create_oval(x1 + (column_width/4),y1,x1 + (3*column_width/4),y2,fill=oppcolor)
            self._canvas.after(50, lambda: self.animateFlips(3))
        elif i == 3:
            self._canvas.create_oval(x1 + (column_width/2),y1,x1 + (column_width/2),y2,fill=oppcolor)
            self._canvas.after(50, lambda: self.animateFlips(4))
        elif i == 4:
            self._canvas.create_oval(x1 + (column_width/4),y1,x1 + (3*column_width/4),y2,fill=color)
            self._canvas.after(50, lambda: self.animateFlips(5))
        elif i == 5:
            self._canvas.create_oval(x1,y1,x2,y2,fill=color)
            newBoard[x][y] = Othello.nextTurn(self._game.turn)
    self._game = GameState(board = newBoard, turn = self._game.turn, skipped = 0)
    self.displayMoves()
    self.displayButtons()
    self.displayInfo()
    self.displayWinner(self.getWinner())
    self._canvas.bind('<Configure>',self.draw_handler)

Upvotes: 3

Views: 62

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386352

The simplest solution is to not delete and recreate the game pieces on each iteration. Draw them once, and then use the itemconfig method to alter the appearance of the game pieces.

Even better would be to create a GamePiece class so that each piece is represented by this class. Then, move the animation function inside the class. This will make your main logic much easier to understand.

Upvotes: 2

Related Questions