5
\$\begingroup\$

I took my basic Word jumble game and added some additional features to learn new stuff. My plan was not to have any pre-defined words coded in my python script but rather different group of words in a text file that are being imported into the game. In my case these were: sad_words.txt, amazement_words.txt.

I made interfaces for the user to add words, to browse the words by group name and to delete a specific group.

After importing a list of words, the user can play the game, first selecting a group of words. Then the user is given four jumbled words and at the end the score of the number of words he/she gets right.

The score for the most recent game is also recorded in a file that can be accessed by the user from the main menu.

For the storage of word groups and scores I used shelve.

import random
import shelve

# Welcome the player
print("""
    Welcome to Word Jumble.
        Unscramble the letters to make a word.
""")

def menu():
    print("1--Play the game")
    print("2--Browse a word set")
    print("3--Add a new word set")
    print("4--Delete a word set")
    print("5--My sorted scores")
    print("6--Exit")
    pick = int(input("Pick one:"))

    if pick == 1:
        shelf = shelve.open("wordlists.dat")
        for key in shelf.keys():
            print(key)
        word_set = input("Pick one:")
        if word_set != key:
            word_set = input("Type in the correct set: ")
        global wordlist
        wordlist = shelf[word_set]
        game()

    elif pick == 2:
        browse()

    elif pick == 3:
        global name
        name = input("Name: ")
        filename = input("File name:")
        add_list(filename)

    elif pick == 4:
        delete()

    elif pick == 5:
        score()

def browse():
    print("Retrieving word list from shelf")
    shelf = shelve.open("wordlists.dat")
    for key in shelf.keys():
        print(key)
    name = input("Which one?")
    if name != key:
        name = input("Which one?")
    print("Your words: {}".format(shelf[name]))
    shelf.close()
    return menu()

def game():
    score = 0
    for i in range(4):
        word = random.choice(wordlist)
        theWord = word
        jumble = ""
        while(len(word) > 0):
            position = random.randrange(len(word))
            jumble += word[position]
            word = word[:position] + word[position + 1:]
        print("The jumble word is: {}".format(jumble))

        # Getting player's guess
        guess = input("Enter your guess: ").lower()

        # congratulate the player
        if(guess == theWord):
            print("Congratulations! You guessed it")
            score += 1

        else:
            print("Sorry, wrong guess.")
    print("You got {} out of 10".format(score))
    shelf = shelve.open("score.dat")
    shelf["score"]=[score]
    shelf.sync()
    shelf.close()
    return menu()

def score():
    shelf = shelve.open("score.dat")
    for key in shelf.keys():
        print(shelf[key])
    shelf.close()
    return menu()

def add_list(file):
    with open(file) as afile:
        the_list = [word.strip(",") for line in afile for word in line.split()]
        print(the_list)
    print("Shelving Lists ...")
    shelf = shelve.open("wordlists.dat")
    shelf[name] = the_list
    shelf.sync()
    shelf.close()
    print("Success.")
    print("Retrieving word list from shelf")
    shelf = shelve.open("wordlists.dat")
    print("Your words: {}".format(shelf[name]))
    shelf.close()
    return menu()

def delete():
    shelf = shelve.open("wordlists.dat")
    for key in shelf.keys():
        print(key)
    delete_key = input("Do you want to delete:")
    if delete_key == key in shelf.keys():
        del shelf[key]
        shelf.sync()
        shelf.close()
    else:
        print("Please type in the correct file")
        return delete()
    return menu()
menu()

Any other suggestions how to improve it (especially code structure and re-usability - should I use modules?) would be very helpful as I am a total beginner and began Python 6 weeks ago.

\$\endgroup\$
2
\$\begingroup\$

First off, really great work!

The first thing that jumped out was how you start the game loop (printing the welcome message and calling menu() at the bottom.

I would use this handy little guy:

if __name__ == "__main__":
   print('Welcome Message')
   menu()

This says: if my __name__ is "__main__" (which is what happens when you say: python wordgame.py you will run the code in that block.

Next up is the use of global. Obviously, you want to be able to pass around some data while you play the game. This is a great job for an object or a dictionary.

To make this work nicely, add a parameter to the menu function (since this is for now your entry point) called state.

def menu(state=dict()):
    # some code
    state['wordlist'] = wordlist
    # more code
    state['name'] = name

This will make testing (another noble pursuit) much easier because you can inject a state into your game and test things out without having to play through all the scenarios!

This is not a full solution to passing around a state dictionary, but maybe you'll want to do that in your new block defined above (maybe with some defaults).

Next up, a common python construct you will start seeing more and more as you spend time in the community is a context manager. Context Managers are a lot like functions, they take away some of the boilerplate code and let us get down to business.

def delete():
    with shelve.open('wordlists.dat') as shelf:
        for key in shelf.keys():
            print(key)
        delete_key = input("Do you want to delete:")
        if delete_key == key in shelf.keys():
            del shelf[key]
            shelf.sync()
        else:
            print("Please type in the correct file")
            return delete()
    return menu()

What's the difference? Now every time we call the delete function, we open the file automatically and close it automatically after we break out of that block.

There are of course many more things that could be done but great work so far and please feel free to leave comments and so forth to keep the conversation going.

\$\endgroup\$
  • \$\begingroup\$ Thank you for this, really helpful! I will keep posting the updated code in here as I want to add some other features as well after going through tutorials. \$\endgroup\$ – Jure Štabuc Nov 10 '16 at 18:21
  • \$\begingroup\$ Happy to help, I also forgot to mention that the UX for this game is great but you could get even more out of it with some exception handling - especially when it comes to the word list files. \$\endgroup\$ – theWanderer4865 Nov 10 '16 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.