7
\$\begingroup\$

I'm trying to learn programming with python by myself and I've made a hangman game for exercise purposes.

import random

words = ['egypt', 'automobile', 'world', 'python', 'miniority', 'treehouse', 'friend', 'program' , 'people']

def start():
    print "Hello! Welcome to a tiny hangman game that I made for exercise purposes."
    raw_input('Press enter to continue')

    key = random.randint(0,(len(words)-1))

    global word
    word = words[key]

    global word_template
    word_template = '_' * len(word)
    word_template = list(word_template)

    guesser()

def draw(int):
    if int == 0:    
        print " _________     "
        print "|         |    "
        print "|              "
        print "|              "
        print "|              "
        print "|              "
        print "|              "
    elif int == 1:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|              "
        print "|              "
        print "|              "
        print "|              "
    elif int == 2:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|         |    "
        print "|              "
        print "|              "
        print "|              "
    elif int == 3:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|        /|    "
        print "|              "
        print "|              "
        print "|              "
    elif int == 4:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|        /|\\  "
        print "|              "
        print "|              "
        print "|              "
    elif int == 5:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|        /|\\  "
        print "|        /     "
        print "|              "
        print "|              "
    elif int == 6:
        print " _________     "
        print "|         |    "
        print "|         0    "
        print "|        /|\\  "
        print "|        / \\  "
        print "|              "
        print "|              "

def guesser():
    global counter
    counter = 0
    checker = list(word)
    guesses = []
    while counter < 6:
        draw(counter)
        print word_template
        print '\nYour previous letters are:',  guesses
        print 'You have ',(6 - counter), 'guesses left.'
        choice = raw_input('Choose a letter: ')
        if choice in guesses:
            print "\nYou made that guess before!"
        elif choice in checker:
            if checker.count(choice) == 1:
                pointer = checker.index(choice)
                word_template[pointer] = checker[pointer]
                checker[pointer] = 1
                guesses.append(choice)
                print "\nThat's a hit!"
                if list(word) == word_template:
                    win()
                else:
                    continue
            elif checker.count(choice) > 1:
                for i in range(0, checker.count(choice)):
                    pointer = checker.index(choice)
                    word_template[pointer] = checker[pointer]
                    checker[pointer] = 1
                guesses.append(choice)
                print "\nWOW! That was a multiple hit!"
                if list(word) == word_template:
                    win()
                else:
                    continue
        elif choice not in checker:
            guesses.append(choice)
            counter += 1
            print '\nMiss!'
    if counter == 6:
        draw(counter)
        print 'Sorry, you lose :('
        print 'The word was:', word
        retry()

def win():
    print "\nYou won!"
    print "You found the word:", word
    retry()

def retry():
    print "Do you want to play again?"
    choice = raw_input('Type retry for restart, Ctrl + C for exit:')
    if choice == 'retry':
        start()
    else:
        print "Sorry, I can't understand."
        retry()

start()

Is there any flaws on my logic and what can you suggest me to improve my code?

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Code Review! I hope you get great answers! \$\endgroup\$ – Tunaki May 6 '16 at 17:24
  • 2
    \$\begingroup\$ hahaha I love your first print statement! \$\endgroup\$ – Joseph Farah May 6 '16 at 18:03
  • 1
    \$\begingroup\$ Use a decorator and create a hangman object. That way , you can just call things like .addRightArm and it will recreate the arm string in a list of strings. You can store the state of the hangee as an integer to test for the condition. \$\endgroup\$ – Andrew Scott Evans May 6 '16 at 21:44
6
\$\begingroup\$

Avoid global variables

Instead of using global variables, it would be better to reorganize the code so that values are passed around in function parameters as necessary.

Don't use int as variable name

int is the name of a built-in type. Don't use it as a variable name. It prevents the rest of the code from using it, and it's confusing for readers.

Don't use recursive menu

In the current implementation the menu uses recursive logic: start calls guesser, which will call win or retry, which will again call start, or retry, and so on. This is all very confusing, and leads to a long stack. Rewrite this to use a loop for the game menu instead of recursion.

Use the print function

I know you tagged your question with , but with the simple change of print something to print(something) you get something that works just as well, and you're one step closer to compatibility with Python 3, and building a good habit.

\$\endgroup\$
8
\$\begingroup\$

That's so awesome you are learning Python! I love it and I am sure you will too.

Your code looks pretty good! I played it and enjoyed doing so. It's harder than I expected though!

So here are a few quick ideas for how you could improve your code.

Fewer print statements with """

Instead of printing each line separately to create the hangman, you could use triple quotation marks to print it as a block. For example, instead of this:

print " _________     "
print "|         |    "
print "|         0    "
print "|        /|\\  "
print "|        / \\  "
print "|              "
print "|              "

...you can try this:

print """
 _________     
|         |    
|         0    
|        /|\\  
|        / \\  
|              
|              
"""

Add a space for readability

This is a minor issue, but it helps if you add a space in your string that is being printed for the user input. So instead of this:

        choice = raw_input('Type retry for restart, Ctrl + C for exit:')

I would recommend this (note the space after the colon):

        choice = raw_input('Type retry for restart, Ctrl + C for exit: ')  

Also note that you don't have to do this for print statements where you've added an argument, because with a line of code like print 'The word was:', word Python will insert automatically insert a space between the two strings.

Wrapping more with start() aka main()

One last thing, and this is a more advanced concept. You did a good job by wrapping most of your code with the start() function. In most code I see it is more conventional to call this main() and it also will make more sense when you see the main in other languages as well. But whether you call it main() or start(), I would add your words list inside of it, like so:

def start():
    words = ['egypt', 'automobile', 'world', 
             'python', 'miniority',   # Isn't this spelled 'minority' ?
             'treehouse', 'friend', 'program' , 'people']

    print "Hello! Welcome to a tiny hangman game that I made for exercise purposes."
    raw_input('Press enter to continue')    

    key = random.randint(0,(len(words)-1))    

    global word
    word = words[key]    

    global word_template
    word_template = '_' * len(word)
    word_template = list(word_template)    

    guesser()

It's also customary to have your main() function at the very bottom of your script, so I would move your start() function to the very end of your file, but above where you are actually executing start()

From future import print_function

Building on the answer that @janos provided, I make it a habit to add this to the top of all of my Python2.X code, so that it's easier to transition it to Python3 if and when you are ready to do so:

from __future__ import print_function

I would then try and go back through all of your print statements and change it to the print() convention that @janos described. Note that you should add this as the very first import, above import random.

Hope that helps! Great job, keep at it and happy coding!

\$\endgroup\$

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.