0

I'm writing a program with a GUI for school.

I'm supposed to write Pah Tum. Its played on a 7x7 matrix. My console game is done and works perfectly, but I'm struggling with Tkinter right now.

So far I have a few frames inside frames defined in my __init__ function.

So now the first problem:

I could make a 7x7 board like this:

for x in range(0, 7):
    for y in range(0, 7):
            self.button = Button(self.board, command=self.action)
            self.button.grid(row = x, column = y)

So what I want to do now is, every time I hit a button I want to change the color to red (for player 1) or blue (if its player 2s turn).

    self.turn_tracker = 0  # is in __init__

def action(self):
    if self.turn_tracker in range(0, 49, 2):
        self.turn_tracker += 1
        self.button.configure(bg="blue")

    elif self.turn_tracker in range(1, 49, 2):
        self.turn_tracker += 1
        self.button.configure(bg="red")

    elif self.turn_tracker == 49:
        print("game over")
        sys.exit() #calculate

This will only change the button at 6x6. So what I tried is defining every button separately and having a change method for every button separately as well. As you can imagine this looks really really ugly but it works at least.

What can I do to make it more efficient? Thanks for any help!

j_4321
  • 15,431
  • 3
  • 34
  • 61
Marcel
  • 35
  • 6
  • yesterday was similar question with red buttons on 7x7 grid: [Python Tkinter - Dictionary with Buttons - how do you disable them?](https://stackoverflow.com/questions/47821717/python-tkinter-dictionary-with-buttons-how-do-you-disable-them) – furas Dec 15 '17 at 04:39
  • you have to keep buttons on list. `self.button` can keep only one button - and it keeps last one. – furas Dec 15 '17 at 04:40
  • He must be working on the same task. I'll have a look at it, thank you! – Marcel Dec 15 '17 at 04:45

1 Answers1

0

You can still define your buttons in a loop and associate to them different commands. For instance you can store the buttons in a 7x7 matrix self.buttons and make action take the row and column as arguments:

def action(self, x, y):
    if self.turn_tracker in range(0, 49, 2):
        self.turn_tracker += 1
        self.buttons[x][y].configure(bg="blue")

    elif self.turn_tracker in range(1, 49, 2):
        self.turn_tracker += 1
        self.buttons[x][y].configure(bg="red")

    elif self.turn_tracker == 49:
        print("game over")

And the matrix of buttons is created in __init__ with

    self.buttons = []
    for x in range(0, 7):
        self.buttons.append([])
        for y in range(0, 7):
            button = tk.Button(self.board, command=lambda row=x, column=y: self.action(row, column))  
            self.buttons[x].append(button)
            button.grid(row=x, column=y)

I use lambda row=x, column=y: self.action(row, column) and not directly lambda: self.action(x, y) because at the end of the loop x=6 and y=6, so when I would click on a button, it will alwys be the color of the last button that would change (see Tkinter assign button command in loop with lambda).

j_4321
  • 15,431
  • 3
  • 34
  • 61