HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Simple Python hangman game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gamesimplepythonhangman

Problem

I've created a little hangman game. It's pretty simple, and not to exciting but I want to know if there's a way I could turn this little game into something more extravagant and more exciting. How can I take this delicate piece of crap machinery into something a little more fun and a bit more complicated? For example:

  • Can I turn the list that is shown into a single string?



  • Is there a better way to use a random word?



  • Am I using the for and while loop in the correct syntax?



Source:

```
from random import randint

WORD_LIST = {
'rand_word_1': 'sergeanty',
'rand_word_2': 'amphipneustic',
'rand_word_3': 'hypochil',
'rand_word_4': 'grus',
'rand_word_5': 'depressed',
'rand_word_6': 'distortedly',
'rand_word_7': 'unselected',
'rand_word_8': 'crakow',
'rand_word_9': 'preendorsing',
'rand_word_10': 'convenient'
}

HANGMAN = (
"""
x-------x
""",
"""
x-------x
|
|
|
|
|
""",
"""
x-------x
| |
| 0
|
|
|
""",
"""
x-------x
| |
| 0
| |
|
|
""",
"""
x-------x
| |
| 0
| /|\\
|
|
""",
"""
x-------x
| |
| 0
| /|\\
| /
|
""",
"""
x-------x
| |
| 0
| /|\\
| / \\
|
GAME OVER
"""
)

MAX = len(HANGMAN) - 1
num = randint(1, 10)
num_string = str(num)
words = 'rand_word_{}'.format(num_string)
WORD_TO_GUESS = WORD_LIST[words]
HIDDEN = ['_'] * len(WORD_TO_GUESS)
LETTERS_GUESSED = []

def begin_game():
hang_size = 0
print "\tHANGMAN!"
word_arr = list(WORD_TO_GUESS)

while hang_size < MAX:
print str(HIDDEN)
user_guess = raw_input('Guess a letter dude: ')

if user_guess in LETTERS_GUESSED:
print 'You already guessed that.. PAY ATTENTION!'
user_guess = raw_input('Guess a letter dude: ')

Solution

Overview

I can see that you are a beginner and that is totally fine! Some of the points I will be making might, sound a bit harsh and go over your head. If they do try to improve the parts of the code you do understand, and instead post a follow up question.

LMGTFY / RTFM

Asking a question on a SE, site is a great way to learn. However another is searching for answers beforehand. In fact all three questions in your bullet list could be googled / found in the manual.

  • Turn a list into a string Python



  • How do I randomly select an item from a list using Python?



  • When to use for and while loop



As you know CodeReview has it's own hangman tag -- since you tagged your own question with the tag. This means people have asked hangman related questions earlier, and you could have browsed these questions before posting your own. As an example, even I have asked a question about hangman. Here is another very similar question.

This is not to discredit you for asking, however drawing suggestions and inspiration from similar problems is a fantastic way to learn.

PEP 8 - Style Guide for Python Code

As to pick the lowest hanging fruits. Consistency is a key part of programming, as it greatly increases readability. It also tells a bit about the coders eye for detail. Lets' look at how you have named your global constants:

MAX
num 
num_string 
words 
WORD_TO_GUESS 
HIDDEN 
LETTERS_GUESSED


Do you see the inconsistency? Pep 8 recommends the following naming-conventions:

  • CAPITALIZED_WITH_UNDERSCORES for constants



  • UpperCamelCase for class names



  • lowercase_separated_by_underscores for other names



General structure

A very rough sketch of how a standard python program should look like is as follows

import

global CONSTANTS
global VARIABLES

functions

classes

if __name__ == '__main__':

    main()


All of your code should be split into short simple functions, which each serve a single purpose. You should in general have as little code as possible floating around that is not part of a function. This includes minimizing the need for global variables and constants. There are some exceptions to this rule, however your code is not one of them.

Some more pointers

As earlier answers stated you can change your dictionary word list into

WORD_LIST = [
    'sergeanty',
    'amphipneustic',
    'hypochil',
    'grus',
    'depressed',
    'distortedly',
    'unselected',
    'crakow',
    'preendorsing',
    'convenient'
]


As mentioned earlier you use too many global variables. This

MAX = len(HANGMAN) - 1
num = randint(1, 10)
num_string = str(num)
words = 'rand_word_{}'.format(num_string)
WORD_TO_GUESS = WORD_LIST[words]
HIDDEN = ['_'] * len(WORD_TO_GUESS)
LETTERS_GUESSED = []


can be shortened into

MAX = len(HANGMAN) - 1
word_to_guess = random.choice(WORD_LIST)
hidden = ['_'] * len(word_to_guess)
letters_guessed = set()


Where I have used the choice function from the random module. For an example of use see below

>>> import random
   >>> a = ["Stack", "Overflow", "rocks"]
   >>> print(random.choice(a))
   rocks


for a more detailed explanation see the second bullet point at the start.

You might also have noticed that some of the variables are not CAPITALIZED that is because they do not need to be global variables, and can be moved into the main function.

def play_hangman():
    hang_size = 0
    word_to_guess = random.choice(WORD_LIST)

    hidden = ['_'] * len(word_to_guess)
    letters_guessed = set()


Note how I also conveniently changed the name of your main() function. Naming variables, functions and classes in programming is one of the more difficult things to do. A general rule of thumb is that the names should be clear, distinct and succinct in that order. As others have pointed out main() only achieves the third, which should be the last thing to worry about.

Handling user input



Jokes aside as a rule you should never except the user to use the correct input syntax. Instead you should build in checks, exceptions to handle these errors.

For an example your code only checks once if I have tried the letter before.

if user_guess in LETTERS_GUESSED:
    print 'You already guessed that.. PAY ATTENTION!'
    user_guess = raw_input('Guess a letter dude: ')


One way to fix this is using a while loop instead

while user_guess in LETTERS_GUESSED:
    print 'You already guessed that.. PAY ATTENTION!'
    user_guess = raw_input('Guess a letter dude: ')


What happens if i decide to try the letter banana or the letter `? Your function does nothing to handle it. What If I try the more common mistake to try A then a? All of this can be fixed by putting the get_user_input into it's own function

``
ALPHABETH = 'abcdefghijklmnopqrstuvwxyz'

def guess_letter(letters_guessed):
while True:
guess = raw_input('Guess a letter dude: ').lower()
if guess not in ALPHABETH:
print g

Code Snippets

MAX
num 
num_string 
words 
WORD_TO_GUESS 
HIDDEN 
LETTERS_GUESSED
import

global CONSTANTS
global VARIABLES

functions

classes

if __name__ == '__main__':

    main()
WORD_LIST = [
    'sergeanty',
    'amphipneustic',
    'hypochil',
    'grus',
    'depressed',
    'distortedly',
    'unselected',
    'crakow',
    'preendorsing',
    'convenient'
]
MAX = len(HANGMAN) - 1
num = randint(1, 10)
num_string = str(num)
words = 'rand_word_{}'.format(num_string)
WORD_TO_GUESS = WORD_LIST[words]
HIDDEN = ['_'] * len(WORD_TO_GUESS)
LETTERS_GUESSED = []
MAX = len(HANGMAN) - 1
word_to_guess = random.choice(WORD_LIST)
hidden = ['_'] * len(word_to_guess)
letters_guessed = set()

Context

StackExchange Code Review Q#135236, answer score: 11

Revisions (0)

No revisions yet.