I have this code for a basic TicTacToe game, using Tkinter:
from tkinter import *
from functools import partial
class Window(Frame):
    def __init__(self, master = None): # init Window class
        Frame.__init__(self, master) # init Frame class
        self.master = master # allows us to refer to root as master
        self.rows = 3
        self.columns = 3
        self.buttonGrid = [[None for x in range(self.rows)] for y in range(self.columns)]
        self.create_window()
        self.add_buttons()
    
    def create_window(self):
        #title
        self.master.title('Tic Tac Toe')
        self.pack(fill = BOTH, expand = 1)
        for i in range(0,3): # allows buttons to expand to frame size
            self.grid_columnconfigure(i, weight = 1)
            self.grid_rowconfigure(i, weight = 1)
    
    def add_buttons(self):
        rows = 3
        columns = 3
        # create a 2d array to put each button in
        # Creates a list containing 3 lists, each of 3 items, all set to None
        for i in range (rows):
            for j in range(columns):
                button_ij = Button(self, textvariable = self.buttonGrid[i][j], command = lambda: self.add_move(i, j))
                # sticky centres buttons and removes space between adjacent buttons
                button_ij.grid(row = i,column = j, sticky =E+W+S+N)
                
    def add_move(self, i,j): # only 2 and 2 passed in as i and j
        self.buttonGrid[i][j] = 'X'
        print(i, j)
        print(self.buttonGrid)
root = Tk() # creating Tk instance
rootWidth = '500'
rootHeight = '500'
root.geometry(rootWidth+'x'+rootHeight)
ticTacToe = Window(root) # creating Window object with root as master
root.mainloop() # keeps program running
In add_buttons, I am adding the buttons into row i, column j. However, when I call add_move, the i and j values always show up as 2, 2 - so only the last element in the last list of buttonGrid gets changed.
Why does this happen? How can I pass other position values into the add_move method?
 
    