Что-то не так без ошибок - Включает Tkinter - PullRequest
0 голосов
/ 26 ноября 2011

Я не получаю никакой ошибки, но код не выполняет то, что я хочу, поэтому в коде должно быть где-то, где я допустил ошибку. То, что я хочу сделать, - это если слова совпадают, тогда слова должны быть парой, и две выбранные ячейки должны оставаться «self.hidden = False», и поэтому ячейки должны все еще показывать слова за двумя ячейками. Иначе, если слова не совпадают, ячейки должны быть «self.hidden = True», а в двух ячейках должно быть «---».

Вот важные части:

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()

1 Ответ

1 голос
/ 26 ноября 2011

Непосредственная проблема заключается в том, что вы не звоните 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. Это намного проще, чем вы думаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...