tkinter和拼字游戏求解器问题

时间:2013-12-07 00:39:25

标签: python class tkinter python-3.3

我必须学习python 3.3.3的逻辑和设计课程。我对编程非常陌生,下面的代码是我在10周内自学的结果。我的程序在程序级别上运行良好,没有GUI。我的程序是一个典型的拼字游戏解算器。我和tkinter度过了一段可怕的时光。我需要从输入到主模块的输入,并将结果输入到列表框。我甚至放弃了从他主要的类中传递参数,所以我将机架和结果设置为全局变量。我明白,对于有人提供帮助可能会有太多的麻烦,但是在决赛之前我会非常感激地帮助我完成任务。提前谢谢你。

#only reason these are global is because im having trouble with tkinter and
#passing the proper parameters to the main module

global results
global rack

import tkinter as tk

#class for GUI
class application:
    def __init__(self):


       self.main=tk.Tk()


         #top fram includes rack label, rack entry, rack enter button and quit button
       self.top_frame = tk.Frame(self.main)

       self.main.title('Scrabble Solver')
       self.main.geometry('300x300')
       self.main.wm_iconbitmap('favicon.ico')

       self.racklbl = tk.Label(self.top_frame, text="Enter your rack")
       self.racklbl.pack()

       self.rackent=tk.Entry(self.top_frame)
       self.rackent.pack(side="left")

       self.rackbtn = tk.Button(self.top_frame, text = "Enter",
command=self.getRackData)
       self.rackbtn.pack(side="left")

       self.top_frame.pack()



       #bottom frame includes listbox for results display and scrollbar

       self.bot_frame = tk.Frame(self.main)

       self.validlist = tk.Listbox(self.bot_frame, width=30)
       self.validlist.pack(side="left")

       self.scrollbar = tk.Scrollbar(self.bot_frame)
       self.scrollbar.pack(side="right", fill="y")

       self.QUIT = tk.Button(self.top_frame, text="QUIT",                       fg="red", command=self.main.destroy)
       self.QUIT.pack(side='left')

       self.bot_frame.pack()

       tk.mainloop()


    def showError(self):
        tk.messagebox.showinfo('You have entered too many letters')
    def getRackData(self):
        rack = input(self.rackent.get())



def main():
    rack=""
    gui = application() 


    #dictionary for the scores
    scores = {"A": 1, "C": 3, "B": 3, "E": 1, "D": 2, "G": 2,
             "F": 4, "I": 1, "H": 4, "K": 5, "J": 8, "M": 3,
             "L": 1, "O": 1, "N": 1, "Q": 10, "P": 3, "S": 1,
             "R": 1, "U": 1, "T": 1, "W": 4, "V": 4, "Y": 4,
             "X": 8, "Z": 10}


    #get the rack letters
    #rack = getRackLetters(gui)
    #call module to put file into an array
    rack = getRackLetters(rack,gui)
    putFileIntoArray(rack, scores)


# function to get rack letters 
def getRackLetters(rack,gui):
    rack = rack.upper()
    #call function to verify number of letters entered
    verify= verifyRackLetters(rack)
    if verify == True:
        return rack
    else:
        gui.showError()
        main()
#function to verify number of letters entered    
def verifyRackLetters(rack):
    if len(rack) <= 8:
        verify = True
    else:
        verify = False
    return verify

#module to put file into an array    
def putFileIntoArray(rack, scores):
    words = []
    file = open("dict.dat", "r")   

    for line in file:
        line = line.strip()
        words.append(line)

    file.close()
    #call module to find and create an array of valid words then score them
    findValidWords(words, scores)



# module to find and create an array of valid words then score them
def findValidWords(words, rack, scores):

    valid = []
    for word in words:

        candidate = True
        rack_letters = list(rack)

        for letter in word:
            if letter not in rack_letters:
                candidate = False
            else:
                rack_letters.remove(letter)
        #score the valid words and append to list
        if candidate == True:
            total = 0
            for letter in word:
                total = total + scores[letter]
            valid.append([total, word])

    #call module to sort and print the valid words list with scores
    scoreValidWords(valid)

    #module to sort and print the list
def scoreValidWords(valid):
valid.sort()

    for entry in valid:
        score = entry[0]
        word = entry[1]
        results.append(str(score) + " " + word)


    print(results)
main()

1 个答案:

答案 0 :(得分:4)

虽然我删除了滚动条(我想你会弄清楚如何添加它)我完全重写了你的代码,更加pythonic,更容易阅读和写。但是我尽可能地坚持你的代码。

我猜它现在正在运作:

enter image description here enter image description here

以下是我使用的dictionary.dat

beast
lemon
ape
apple
sea
pea
orange
bat

以下是代码本身:

# Import python modules
import tkinter
import tkinter.messagebox
from collections import Counter

# Module level constants
SCORES = {'A': 1, 'C': 3, 'B': 3, 'E': 1, 'D': 2, 'G': 2, 'F': 4, 'I': 1,
          'H': 4, 'K': 5, 'J': 8, 'M': 3, 'L': 1, 'O': 1, 'N': 1, 'Q': 10,
          'P': 3, 'S': 1, 'R': 1, 'U': 1, 'T': 1, 'W': 4,  'V': 4, 'Y': 4,
          'X': 8, 'Z': 10}

class App(tkinter.Tk):

    def __init__(self, word_list, *args, **kwargs):
        # Initialize parent class by passing instance as first argument
        tkinter.Tk.__init__(self, *args, **kwargs)

        # Store values
        self.word_list = word_list

        # Setup main window
        self.title('Scrabble Solver')

        # Create widgets
        rack_label = tkinter.Label(self, text='Enter your rack')
        self.rack_entry = tkinter.Entry(self)
        rack_button = tkinter.Button(self, text='Enter', command=self.search)
        quit_button = tkinter.Button(self, text='Quit', command=self.quit)
        self.valid_list = tkinter.Listbox(self, width=40, font='Courier')

        # Place widgets
        rack_label.grid(row=0, column=0, sticky=tkinter.W)
        self.rack_entry.grid(row=1, column=0, sticky=tkinter.W)
        rack_button.grid(row=1, column=1, sticky=tkinter.W)
        quit_button.grid(row=1, column=2, sticky=tkinter.W)
        self.valid_list.grid(row=2, columnspan=3, sticky=tkinter.W)

    def run(self):
        # Enter event loop
        self.mainloop()

    def error(self):
        # Throw and error message dialog
        tkinter.messagebox.showinfo('You have entered too many letters!')

    def search(self):
        # Cleanup up valid list
        self.valid_list.delete(0, tkinter.END)
        # Get data of entry, and make them lower case
        rack = self.rack_entry.get().lower()
        # Check length of data
        if len(rack) <= 8:
            return self.find_valid_words(rack)
        self.error()

    def find_valid_words(self, rack):
        # Create a dictionary for valid words and its values
        valid = {}
        rack_chars = Counter(rack)
        for word in self.word_list:
            word_chars = Counter(word)
            if word_chars == word_chars & rack_chars:
                valid[word] = sum(SCORES[letter.upper()] for letter in word)

        # Sort the results and insert them into the list box
        if valid:
            for word, score in sorted(valid.items(), key=lambda v: v[1], reverse=True):
                self.valid_list.insert(tkinter.END, '{:<10} {}'.format(word, score))
        else:
            self.valid_list.insert(tkinter.END, 'No results found.')

if __name__ == '__main__':
    # Open dictionary file and scan for words
    with open('dictionary.dat', 'r') as f:
        all_words = [word for word in f.read().split()]
    # Create instance and call run method
    App(all_words).run()