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

Hangman with ASCII

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

Problem

I have just made a game called Hangman. I have added some stuff which people don't normally use, like cheat-code/s, time.sleep().

How can I improve this, in both readability and methodology?

```
import random
import time

hangman = (

"""
_________
|/
|
|
|
|
|
|___
""",

"""
_________
|/ |
|
|
|
|
|
|___
H""",

"""
_________
|/ |
| (_)
|
|
|
|
|___
HA""",

"""
________
|/ |
| (_)
| |
| |
|
|
|___
HAN""",

"""
_________
|/ |
| (_)
| /|
| |
|
|
|___
HANG""",

"""
_________
|/ |
| (_)
| /|\
| |
|
|
|___
HANGM""",

"""
________
|/ |
| (_)
| /|\
| |
| /
|
|___
HANGMA""",

"""
________
|/ |
| (_)

Solution

password = "python".upper() is redundant, you can just type in "PYTHON".

You should keep the whole list, in case you want to do another choice. And instead store your random choice as word. You also don't need to use str, as a file is read as a string by default. Likewise you don't need to specify 'r' for open, as it's the default there too.

words = open("word.txt", "r").read().split()
word = random.choice(words).upper()


You can manually add newline characters (\n) to print to change this

print " "
print "-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----"
print " "


into this

print "\n-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----\n"


Also I recommend rearranging the start to declare all the constants together. Then get words and word all before priting the welcome message. You can also put them all inside an initialising function, that way you can easier restart a new game.

Like this:

def init():
    wrong = 0
    used = []
    password = "python".upper()
    max_wrong = len(hangman) - 1
    so_far = "*" * len(words)   

    words = open("word.txt", "r").read().split()
    word = random.choice(words).upper()

    print "\n-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----\n"
    print "You need to guess", len(words), "letters word"


You should use whitespace to group stuff together based on what stuff actually fits together:

so_far = "*" * len(words)   
print "You need to guess", len(words), "letters word"
while wrong < max_wrong and so_far != words:

    print hangman[wrong]


This makes it hard to notice that there's a while loop at first. This would be better:

so_far = "*" * len(words)   
print "You need to guess", len(words), "letters word"

while wrong < max_wrong and so_far != words:
    print hangman[wrong]


For reading input, I'd put it in its own function separate and have it loop until there's a valid input.

def enter_letter(used):
    """Loop until the user enters a valid letter"""

    while True:
        inp = raw_input("Pick a letter----->").upper()


I would also add .strip() to the end, to remove any accidental whitespace the user might enter. It will remove any whitespace characters from the start or end of the string.

if inp.isdigit() is True=:
            print "Invalid Input"
            continue


Note, you don't need is True, it's being evaluated as a boolean anyway and I'd put all invalid checks in one if statement.

if not inp.isalpha() or inp.isdigit() or len(inp) != 1:


In your script, you didn't check for an empty input, you should only accept something that is exactly 1 character.

Now you could run your check to see if the letter is already used.

if inp in used:
            print "You've already guessed the letter:", inp
            continue


So back in the main game loop, it will actually just look like this:

inp = enter_letter(used)
    used.append(inp)


And then you can check if it's in the word or not.

This is kind of unnecessary, you can use a for loop with enumerate to get both the index and value of the string at the same time rather than needing to index each time:

for i, char in enumerate(words):
        if inp == char:
            new += inp
        else:
            new += so_far[i]


Since you tagged beginner I wont go deep into it (unless you ask) but you could look into list comprehensions for a way to make this happen in one line. It's basically a way to condense a for loop into a single line to create a list. They're handy but can be confusing. If you want me to explain it here, please comment and I'll edit it in.

I would also recommend that you try to put code in functions more. For example, you could put the end game in a function. The main game loop could be too. They wouldn't add a lot to the current script but they would make it easier to expand or reuse. What if you want different kinds of hangman games, or rules? Separating out parts of how the code operates makes it easier to swap in another one or make changes to a function you're using.

Code Snippets

words = open("word.txt", "r").read().split()
word = random.choice(words).upper()
print " "
print "-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----"
print " "
print "\n-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----\n"
def init():
    wrong = 0
    used = []
    password = "python".upper()
    max_wrong = len(hangman) - 1
    so_far = "*" * len(words)   

    words = open("word.txt", "r").read().split()
    word = random.choice(words).upper()

    print "\n-----Welcome to HANGMAN, You get seven chances to guess the mystery word-----\n"
    print "You need to guess", len(words), "letters word"
so_far = "*" * len(words)   
print "You need to guess", len(words), "letters word"
while wrong < max_wrong and so_far != words:


    print hangman[wrong]

Context

StackExchange Code Review Q#101968, answer score: 3

Revisions (0)

No revisions yet.