I’m not getting any error but the code doesn’t do what I want so there must be somewhere in the code where I have made a mistake. What I want to do is if the words match then the words must be a pair and the two chosen cells should remain “self.hidden = False” and therefore the cells should still show the words behind the two cells. Else if the words doesn’t match then the cells should be “self.hidden = True” and the two cells should show “—“.
Here are the important parts:
from tkinter import *
import random
class Cell:
def __init__(self, word, hidden):
self.word = word
self.hidden = hidden
def show_word(self):
""" Shows the word behind the cell """
if self.hidden == True:
self.hidden = False
else:
self.hidden = True
self.button["text"] = str(self)
if mem.choice1 == None:
mem.choice1 = [self.word, self.hidden]
else:
mem.choice2 = [self.word, self.hidden]
self.check(mem.choice1, mem.choice2)
def check(self, choice1, choice2):
""" Checks if the chosen words are a pair """
tries = 0
if choice1 == choice2:
pass
else:
self.show_word
tries += 1
def __str__(self):
""" Displays or hides the word """
if self.hidden == True:
return "---"
else:
return self.word
class Memory(Frame):
""" GUI application that creates a Memory game """
def __init__(self, master):
super(Memory, self).__init__(master)
self.grid()
self.create_widgets()
self.tries = 0
self.choice1 = None
self.choice2 = None
def readShuffle(self):
""" Creates and organizes (shuffles) the pairs in a list """
# reads the file and creates a list of the words
words_file = open("memo.txt","r")
row = words_file.readline()
words = list()
while row != "":
row = row.rstrip('\n')
words.append(row)
row = words_file.readline()
words_file.close()
# shuffles the words in the list
random.shuffle(words)
# creates 18 pairs of words in a new list
the_pairs = list()
for i in range(18):
the_pairs.append(Cell(words[i],True))
the_pairs.append(Cell(words[i],True))
# shuffles the words in the new list
random.shuffle(the_pairs)
return the_pairs
def create_widgets(self):
""" Create widgets to display the Memory game """
# instruction text
Label(self,
text = "- The Memory Game -",
font = ("Helvetica", 12, "bold"),
).grid(row = 0, column = 0, columnspan = 7)
# buttons to show the words
column = 0
row = 1
the_pairs = self.readShuffle()
for index in range(36):
temp = Button(self,
text = the_pairs[index],
width = "7",
height = "2",
relief = GROOVE,
command = lambda x = index: Cell.show_word(the_pairs[x])
)
temp.grid(row = row, column = column, padx = 1, pady = 1)
column += 1
the_pairs[index].button = temp
if column == 6:
column = 0
row += 1
# total tries
self.label = Label(self)
Label(self,
text = "Total tries: 0",
font = ("Helvetica", 11, "italic")
).grid(row = 7, columnspan = 7, pady = 5)
# a quit button
Button(self,
text = "Quit",
font = ("Helvetica", 10, "bold"),
width = "25",
height = "1",
command = self.quit
).grid(row = 8, column = 0, columnspan = 7, pady = 5)
## def update_tries(self):
## """ Increase tries count and display new total. """
## self.tries += 1
## self.label["text"] = "Total Tries: " + str(self.tries)
def quit(self):
""" Ends the memory game """
global root
root.destroy()
# main
root = Tk()
root.title("Memory")
root.geometry("365x355")
mem = Memory(root)
root.mainloop()
The immediate problem is that you’re not calling
self.show_wordon line 136 inCell.check.(You should also just use
!=here, instead of having apassstatement in yourifclause. Additionally,triesisn’t doing anything here…)However, even if you do call it (i.e.
self.show_word()instead ofself.show_word), you have bigger problems, as you’ll set up an infinite loop if the words are not the same once you do.checkwill callshow_wordwhich will then callcheck, etc, etc.What you need to do is reset
choice1andchoice2and their respective buttons inside yourelsestatement inCell.check.However, to do this, you need to have access to the cell objects in question. As it is, you only pass in their text values and whether or not they’re hidden.
The quick fix is to pass around the cell objects themselves.
First, though, let’s clean your functions up a bit… You have this:
This is equivalent to:
Now, let’s pass around the
Cellinstances themselves, so that we can reset their displayed values.Now, things will work as you intended. However, the second choice will never be displayed if it doesn’t match the first one. (In fact, we could remove the
mem.choice2attribute entirely in this version.)So, instead, let’s only reset the two values on the third click, if they don’t match.
Now, things will behave more or less how you want.
However, there’s still a lot of cleanup and re-factoring that you could do. It would make much more sense to have the
Memoryclass handle checking clicks, etc. Also, have a look at the newreadShufflefunction. You were reading in the file in an amazingly convoluted way. You should probably read over a few basic examples of file usage in python. It’s much simpler than you think.