Непосредственная проблема заключается в том, что вы не звоните self.show_word
на линию 136 в Cell.check
.
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
(Вы также должны просто использовать !=
здесь вместо оператора pass
в вашем предложении if
. Кроме того, tries
ничего не делает здесь здесь ...)
Однако, даже если вы все-таки позвоните (т.е. self.show_word()
вместо self.show_word
), у вас возникнут большие проблемы, поскольку вы создадите бесконечный цикл, если слова не совпадают, как только вы это сделаете.
check
вызовет show_word
, который затем вызовет check
и т. Д. И т. Д.
Что вам нужно сделать, это сбросить choice1
и choice2
и их соответствующие кнопки внутри вашего оператора else
в Cell.check
.
Однако для этого вам нужно иметь доступ к рассматриваемым клеточным объектам. На самом деле, вы только передаете их текстовые значения и независимо от того, скрыты они или нет.
Быстрое решение - обойти сами клетки.
Во-первых, давайте немного очистим ваши функции ... У вас есть это:
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 show_word(self):
""" Shows the word behind the cell """
self.hidden = not self.hidden
self.button["text"] = str(self)
if mem.choice1 is 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 """
if choice1 != choice2:
self.show_word() # Infinite recursion!!
Теперь давайте рассмотрим сами экземпляры Cell
, чтобы мы могли сбросить их отображаемые значения.
def show_word(self):
""" Shows the word behind the cell """
self.hidden = not self.hidden
self.button["text"] = str(self)
if mem.choice1 is None:
mem.choice1 = self
else:
mem.choice2 = self
self.check(mem.choice1, mem.choice2)
def check(self, choice1, choice2):
""" Checks if the chosen words are a pair """
mem.choice1, mem.choice2 = None, None
if choice1.word != choice2.word:
for cell in (choice1, choice2):
cell.hidden = True
cell.button['text'] = str(cell)
Теперь все будет работать так, как вы хотели. Однако второй вариант никогда не будет отображаться, если он не соответствует первому. (На самом деле, мы могли бы полностью удалить атрибут mem.choice2
в этой версии.)
Итак, вместо этого давайте сбросим только два значения на третьем клике, если они не совпадают.
def show_word(self):
""" Shows the word behind the cell """
self.hidden = not self.hidden
self.button["text"] = str(self)
if mem.choice1 is None:
mem.choice1 = self
elif mem.choice2 is None:
mem.choice2 = self
else:
choice1, choice2 = mem.choice1, mem.choice2
mem.choice1, mem.choice2 = self, None
self.check(choice1, choice2)
def check(self, choice1, choice2):
""" Checks if the chosen words are a pair """
if choice1.word != choice2.word:
for cell in (choice1, choice2):
cell.hidden = True
cell.button['text'] = str(cell)
Теперь все будет вести себя более или менее так, как вы хотите.
from tkinter import *
import random
class Cell:
def __init__(self, word, hidden=True):
self.word = word
self.hidden = hidden
def show_word(self):
""" Shows the word behind the cell """
self.hidden = not self.hidden
self.button["text"] = str(self)
if mem.choice1 is None:
mem.choice1 = self
elif mem.choice2 is None:
mem.choice2 = self
else:
choice1, choice2 = mem.choice1, mem.choice2
mem.choice1, mem.choice2 = self, None
self.check(choice1, choice2)
def check(self, choice1, choice2):
""" Checks if the chosen words are a pair """
if choice1.word != choice2.word:
for cell in (choice1, choice2):
cell.hidden = True
cell.button['text'] = str(cell)
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 a list of words from the file
with open('memo.txt', 'r') as infile:
words = [line.strip() for line in infile]
# creates 18 pairs of words in a new list
the_pairs = list()
for i in range(18):
the_pairs.extend([Cell(words[i]), Cell(words[i])])
# 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 = the_pairs[index].show_word
)
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 quit(self):
""" Ends the memory game """
global root
root.destroy()
# main
root = Tk()
root.title("Memory")
root.geometry("365x355")
mem = Memory(root)
root.mainloop()
Тем не менее, вы все еще можете провести большую часть очистки и перефакторинга. Было бы гораздо разумнее иметь ручку класса Memory
, проверяющую клики и т. Д. Также взгляните на новую функцию readShuffle
. Вы читали в файле удивительным *1057* запутанным способом. Вероятно, вам следует прочитать несколько основных примеров использования файлов в Python. Это намного проще, чем вы думаете.