Python - my first game *hangman*

Started by
7 comments, last by Oluseyi 16 years, 2 months ago
Hey everyone. I've taken up learning python. This is my first attempt to create a game. Its a simple hangman game. I feel proud that I finished it, but could yall look over it and give me pointers on what I've done wrong or things I could do better. One problem that I did run into was that if I had a word "backyard" and the user guessed "a" then it would only fill in the first and not the second one. What would be a solution to this problem?

import random
import time

#hangman game
__Author__ = "Alex Mullins"

#the words - hints (this is a list of tuples with the word and corresponding hint
theWords = [("kitchen", "some place that you cook in"),
            ("house", "its a place that you live in"),
            ("friend", "it is someone really close to you")]

#seeding and finding out the random word and hint
random.seed(time.time())
x = random.randint(0, len(theWords) - 1)
finalWord = theWords[x][0]
finalHint = theWords[x][1]

#setting up the amount of incorrectGuesses the user has and the word guessed so far
incorrectGuesses = 5
soFar = "-" * len(finalWord)

#main while loop 
while soFar != finalWord and incorrectGuesses > 0:

    print "You have %d many guesses left" % incorrectGuesses
    userGuess = raw_input("Please input ONE character or 'exit' to quit or 'hint' to get the hint: ")
    userGuess = userGuess.lower()

    #checking to see if the user wants to exit or get a hint
    if userGuess == "exit":
        break
    elif userGuess == "hint":
        print finalHint
        userGuess = raw_input("Please input ONE character or 'exit' to quit or 'hint' to get the hint: ")
    
    #checks to see if the user's guess is in the word and if it is update so far  
    if userGuess in finalWord:
        index = finalWord.find(userGuess)
        x = list(soFar)
        x[index] = userGuess
        soFar = "".join(x)
        print "Yes that guess is in the word"

    #the user didnt guess a correct letter and incorrectguess is reduced    
    else:
        print "Im sorry that letter is not in the word."
        incorrectGuesses = incorrectGuesses - 1

if soFar == finalWord:
    print "Congrats you won!"

else:
    print "Thanks for playing"
        



Thanks a lot!
Advertisement
Having never programmed in Python, this is only a guess for the solution to your "backyard" problem. At the part where you do index = finalWord.find(userGuess), make sure you loop through the whole word. I'm assuming of course that find() is similar to firstIndexOf(char c). You only ever do this once. This must be done for the whole word.
towerofinfinity.blogspot.comgamecodemonkey.blogspot.com
Quote:Original post by alexmullins
One problem that I did run into was that if I had a word "backyard" and the user guessed "a" then it would only fill in the first and not the second one. What would be a solution to this problem?

First of all, congratulations on completing a game! Keep at it, and I'll be expecting great things from you in the future.

The best way to handle situations like "backyard" requires you to reexamine the problem a bit. Rather than trying to replace the asterisks or underscores in the output string you show to the user, replace the letters in a copy of the original string!

# we store the letters the user has *NOT* yet guessednotGuessed = letters(theWords[x][0])# each time we need to display the string to the user, we replace letters not yet # guessed with asterisks:for l in notGuessed:  soFar = finalWord.replace(i, "-") # don't worry, it makes a copy. finalWord isn't changed

That's it! Every time the user correctly guesses a letter, remove it from notGuessed using notGuessed.remove(userGuess), et voilà!

I'm sure you can write the letters() function yourself to return all the unique letters in a word as a list. The more important lesson here is that sometimes the easiest way to do something is ironically sort of backwards. [smile]

Happy hacking!
Congrats on your first game! I don't have much to add over what Oluseyi already mentioned, but I have a suggestion to make your random word selection code more Pythonic.

Replace this...

random.seed(time.time())x = random.randint(0, len(theWords) - 1)finalWord = theWords[x][0]finalHint = theWords[x][1]


with this...

finalWord, finalHint = random.sample( theWords, 1 )[0]


The second code block uses the built-in sample function for retrieving a random element from a sequence. The function returns the result as a list, so the [0] at the end grabs the first (and only) element. Also, I combined the assignment of finalWord and finalHint into a single line using list assignment.

Lastly, Python's random number generator is seeded with the current time by default, so you don't need to manually do it.

Good luck with Python!
thanks guys for the help.
I'd do it this way:

if userGuess in finalWord:  soFar = "".join(    finalChar if userGuess == finalChar else currentChar    for finalChar, currentChar in zip(finalWord, soFar)  )  print "Yes that guess is in the word"else:  print "Im sorry that letter is not in the word."  incorrectGuesses -= 1


But maybe that's just me [grin]

(It means pretty much exactly what it says: Take pairs of characters from finalWord and soFar; with each pair, select the character from the final word if it matches the user guess, and otherwise the character that was already in soFar; join up the results.)

(Edit: I usually use single quotes for strings in Python when possible, but the forum has problems formatting those inside code tags.)
Quote:Original post by doctorsixstring
Replace this...

*** Source Snippet Removed ***

with this...

*** Source Snippet Removed ***

The second code block uses the built-in sample function for retrieving a random element from a sequence. The function returns the result as a list, so the [0] at the end grabs the first (and only) element. Also, I combined the assignment of finalWord and finalHint into a single line using list assignment.


Er, you can do better than that :)

finalWord, finalHint = random.choice(theWords)




Also, a logic problem:

while soFar != finalWord and incorrectGuesses > 0:    print "You have %d many guesses left" % incorrectGuesses    userGuess = raw_input("Please input ONE character or 'exit' to quit or 'hint' to get the hint: ")    userGuess = userGuess.lower()    #checking to see if the user wants to exit or get a hint    if userGuess == "exit":        break    elif userGuess == "hint":        print finalHint        userGuess = raw_input("Please input ONE character or 'exit' to quit or 'hint' to get the hint: ")


Consider what happens if the user asks for a 'hint' twice in a row. [wink] What you really want to do is start the loop over (it's ok - expected, even - to re-print the number of remaining guesses after giving the hint). You can do that with continue.

(Also, you don't need that to be in an 'elif': first off, the input can't be 'exit' and 'hint' at the same time, and second, if it were 'exit', we would have broken out of the loop anyway, so the "else" of 'elif' is implied - it's the only way the code could get to that point!)
Hi guys. I'm back!

@Oluseyi: for some reason I can't figure out what you are trying to show me. If you can, could you try and explain this to me again.

@doctorsixstring: thanks I correctly implemented that into my code. Just can't seem to get my head around what Oluseyi is saying.

edit: Nevermind I figured it out. Thanks alot guys.

Could yall give me a suggestion on another little game that I could try.

[Edited by - alexmullins on February 6, 2008 9:05:58 PM]
Quote:Original post by alexmullins
Could yall give me a suggestion on another little game that I could try.

Anagrams - show a word scrambled up and have users guess what the unscrambled word is.

After that, you can try Crosswords. Then Scrabble. [smile] Build up your skill (and portfolio) by doing a bunch of puzzle games, gradually introducing graphical elements. Before you know it, you'll be making full-featured 3D games.

This topic is closed to new replies.

Advertisement