I'm trying to create a memory game in Python Tkinter. I'm fairly new to tkinter. I created sixteen buttons displaying the cards using a nested for loop and adding each button to a list. My issue is with replacing the card image with a princess image (it's a disney princess memory game). It says the list index is out of range, although it's not supposed to be. Can someone please help me fix it? I've tried solving it in multiple ways with no success. This is my code so far. I haven't finished making the game so that's why some of the variables aren't really used.
Code:
from tkinter import *
from random import choice
screen = Tk()
screen.title("Disney Princesses Memory Game")
width = screen.winfo_screenwidth()
height = screen.winfo_screenheight()
screen.geometry("%dx%d" % (width, height))
screen.configure(bg="#e0bce5")
title = Label(screen, text="Memory Game", font=("David", 50, "underline", "bold"), bg="#e0bce5")
title.place(x=400, y=20)
images_list = [
PhotoImage(file="images/aurora.png"),
PhotoImage(file="images/belle.png"),
PhotoImage(file="images/cinderella.png"),
PhotoImage(file="images/jasmine.png"),
PhotoImage(file="images/mulan.png"),
PhotoImage(file="images/rapunzel.png"),
PhotoImage(file="images/snow white.png"),
PhotoImage(file="images/tiana.png")
]
buttons_list = []
num_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
def replace_card(c, d):
chosen_image = choice(images_list)
check = num_list[images_list.index(chosen_image)]
check += 1
buttons_list[c][d].configure(image=chosen_image)
if check > 2:
num_list.remove(num_list[check])
card = PhotoImage(file="images/card.png")
x = 100
y = 250
for i in range(2):
for j in range(8):
a = Button(screen, image=card, command=replace_card(i, j))
x += 100
a.place(x=x, y=y)
buttons_list.append([a])
y += 100
x = 100
screen.mainloop()
Here's the Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Meirom\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\Meirom\PycharmProjects\memorygame\main.py", line 46, in <lambda>
a = Button(screen, image=card, command=lambda: replace_card(i, j))
File "C:\Users\Meirom\PycharmProjects\memorygame\main.py", line 35, in replace_card
buttons_list[c][d].configure(image=chosen_image)
IndexError: list index out of range
The output that I expect needs to show the generated image on the button that the card is shown on when the card is clicked
Thank you so much to Shoaib Ahmed and to everyone else for all the help! This is the completed program (I need to add more features so it's not exactly finished, but the original error was solved):
from tkinter import *
from random import choice
screen = Tk()
screen.title("Disney Princesses Memory Game")
width = screen.winfo_screenwidth()
height = screen.winfo_screenheight()
screen.geometry("%dx%d" % (width, height))
screen.configure(bg="#e0bce5")
title = Label(screen, text="Memory Game", font=("David", 50, "underline", "bold"), bg="#e0bce5")
title.place(x=400, y=20)
images_list = [
PhotoImage(file="images/aurora.png"),
PhotoImage(file="images/belle.png"),
PhotoImage(file="images/cinderella.png"),
PhotoImage(file="images/jasmine.png"),
PhotoImage(file="images/mulan.png"),
PhotoImage(file="images/rapunzel.png"),
PhotoImage(file="images/snow white.png"),
PhotoImage(file="images/tiana.png")
]
buttons_list = []
chosen_images = []
flipped = []
num_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
card = PhotoImage(file="images/card.png")
def choose_images():
count = 0
for num in range(16):
chosen_image = choice(images_list)
count += 1
if count > 2:
count = 0
reset()
else:
chosen_images.append(chosen_image)
def replace_card(c, d):
global flipped
buttons_list[c][d].configure(image=chosen_images[d])
flipped.append(buttons_list[c][d])
def reset():
global card
for element in flipped:
element.configure(image=card)
choose_images()
x = 100
y = 250
for i in range(2):
buttons_list.append([])
for j in range(8):
a = Button(screen, image=card, command=lambda i=i, j=j: replace_card(i, j))
x += 100
a.place(x=x, y=y)
buttons_list[i].append(a)
y += 100
x = 100
screen.mainloop()