944,084 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Unsolved
  • Views: 12405
  • Python RSS
You are currently viewing page 1 of this multi-page discussion thread
Oct 19th, 2007
0

newbie in need of help for hangman game

Expand Post »
Hi, I'm in need of some help in using functions for the hangman game. The professor doesn't understand how difficult it is for a first time programmer and just doesn't explain new concepts thoroughly. The game that I'm trying to code looks like this:

Enter the secret word: LETTERS

------------------------------------------------------------

Word so far: _______
Misses: 0
What letter would you like to guess? E

Word so far: _E__E__
Misses: 0
.
.
.
.
Word so far: _ETTERS
Misses: 3
What letter would you like to guess? L

You guessed the secret correctly: LETTERS

So Here's what i have so far:
python Syntax (Toggle Plain Text)
  1. #stuff the first person sees
  2. def get_secret(word):
  3. """Get the secret word/phrase"""
  4. input = raw_input(word)
  5. Words_so_far = "_ " * len(word)
  6. Misses = 0
  7. max_wrong = 5
  8.  
  9. #Stuff the second person sees
  10. word = raw_input("Enter the secret word:")
  11. display = len(word)
  12. print display
  13. print word
  14. print "\n"*10
  15. print "_ " * display
  16.  
  17.  
  18. def do_turn(display,misses):
  19. """
  20. Display the current status for the user and let them make a guess.
  21. """

These were the tips the Prof gave, and so I'm just wondering if someone can help me on what the next step is. I can honestly say that it took me 3 hours to type the code that I have shown you. I don't want to get accused for plagiarism of any sort, so I would like a step by step help as if I were going to ask my prof for help. I'm sorry if this post is super long but here's the tips that my prof gave:

Start by creating a function get_secret that asks the user for the secret word/phrase, clears the screen, and returns the secret string.

def get_secret():
"""
Get the secret word/phrase.
"""
In the main part of the program, call the get_secret function and store the result in secret. Create a string display that contains len(secret) underscores.

The string display will be what we show the user as they are guessing. The underscores will be replaced with letters as they are guessed.

Create a variable to count the number of incorrect guesses the user has made (“misses”) and initialize it appropriately. You will also need to keep track of the number of unguessed letters left in the secret: this (along with the count of the misses) will be used to decide when the game is over.

Create a function do_turn that takes two arguments: the display string, and the number of misses made so far. This function should do the part of the turn the user sees (display the part of the secret they have guessed, display the number of misses, and ask them to guess a letter).

def do_turn(display, misses):
"""
Display the current status for the user and let them make a guess.
"""
Don't worry about the error checking (exactly one letter). The function should return the letter the user enters.

Once we have both the secret word, and a guess, we need to be able to update the display string, and keep track of the number of letters discovered. Create a function new_display that takes three arguments: the secret, the display string, and the letter the user guessed.

Once it has these values, the function can calculate the new value for the display string (i.e. replace all of the underscores where the letter the user guessed is the letter). While it does this, it can count the replacements.

Both of those values (the new display string string, and the replacement count) should be returned. A Python function can return multiple values like this:

return newdisp, count
Then, you can call the function and capture both return values like this:

display, count = new_display(…)
Last edited by Eclipse77; Oct 19th, 2007 at 8:30 am.
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Eclipse77 is offline Offline
13 posts
since Oct 2007
Oct 19th, 2007
0

Re: newbie in need of help for hangman game

Well, just to give you a bit of confidence ... the prof has given you good advice. Now for the details ... !

First, you need to plan your code. Make a plan (sometimes called pseudocode) that doesn't go into the details, but clearly and generally spells out exactly how the game will be played. By "generally", I mean that you can say things like

Python Syntax (Toggle Plain Text)
  1. ...
  2. while True:
  3. letter = do_turn
  4. if letter in puzzle and letter not in already_used:
  5. add_to_puzzle
  6. else:
  7. increase_misses
  8. print message
  9. ...

So you can see that the plan doesn't give any details as to HOW some of these steps will happen; it's just a big-picture plan.

Do that first. Post it here if you like, and we can give pointers.

Then, create each function. I would do each function separately and make sure it works by testing it. The testing happens by passing the function typical arguments, and making sure it gives the right return values back.

Thus:

Python Syntax (Toggle Plain Text)
  1. # Code version 1
  2.  
  3. def get_secret():
  4. """Get the secret word/phrase"""
  5. input = raw_input(word)
  6. # etc.
  7.  
  8. # test get_secret
  9. word = get_secret()
  10. print word


Python Syntax (Toggle Plain Text)
  1. # Code version 2
  2.  
  3. def get_secret():
  4. """Get the secret word/phrase"""
  5. input = raw_input(word)
  6. # etc.
  7.  
  8. def do_turn(display, misses):
  9. print display
  10. # etc.
  11.  
  12. # test get_secret
  13. word = get_secret()
  14. print word
  15.  
  16. # test do_turn
  17. display = "_ETTE_"
  18. misses = 2
  19. letter = do_turn(display, misses)
  20. print letter

And so on. The idea here is this:

(1) Each function should do *one* thing. (The version of get_secret in your code tries to do too much, which paradoxically makes it less useful because it has trouble fitting into the big picture.

(2) The purposes of making functions are to (a) isolate actions like do_turn so that you can focus on just doing that one thing (that's the main benefit for you now), and (b) creating code that can be reused elsewhere (that's the main benefit as you get further along).

(3) As you write the functions, focus on the requirements your prof has given. Pay attention to what the function should receive, and make sure it returns what it should return. Functions should, for the most part, not have side effects besides returning the value that is specified.

So: make a plan. Then make functions, one at a time, and test them.

Then finally, put the functions together in your code according to the plan. And it should all work out! (hah-hah...debugging often takes a while )

Hope it helps,
Jeff
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

Thanks for the tips, I'm a bit less frustrated now, since you gave me some ideas that could help me out.

This is my pseudocode that I thought of:

Python Syntax (Toggle Plain Text)
  1. write "Enter the secret word"
  2. .
  3. .
  4. .
  5. write guess a letter
  6. while misses is less than 6 and guess is not equal to secret word
  7. write guess a letter
  8. if letter guessed is in secret word, then
  9. add letter to display and replace underline
  10. else: increase misses by 1
  11. print display
  12. if letters guessed equals secret word
  13. print congratulations, you got the secret word

Here's my new code so far, and I'm still stuck on how to get the user to guess a letter and for it to display the underscores and misses from the function "do_turn". I guess I'm having trouble understanding "calling/returning" a function that's defined. Do i call in the function or out the function? Also, when asking the user for a letter, do i ask in the function or out?

So here's my code so far, and it isn't running too smoothly either. Any help would be great. I really appreciate it.

python Syntax (Toggle Plain Text)
  1. #stuff the first person sees
  2. def get_secret(secret):
  3. """Get the secret word/phrase"""
  4. guess = raw_input(secret)
  5.  
  6.  
  7. #Stuff the second person sees
  8. def do_turn(display,misses):
  9. """
  10. Display the current status for the user and let them make a guess.
  11. """
  12. misses=0
  13. guess = raw_input("What letter would you like to guess?")
  14. while misses < 6 and guess!=secret:
  15.  
  16. for i in range(len(secret)):
  17. if guess != secret[i]:
  18. misses = misses +1
  19. print str(misses)
  20. display = "_ " * len(secret)
  21. print display
  22.  
  23. guess = get_secret(secret)
  24. print guess
  25.  
  26.  
  27. letter = do_turn(display,misses)
  28. print letter

Thanks again!
Last edited by Eclipse77; Oct 20th, 2007 at 8:16 am.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Eclipse77 is offline Offline
13 posts
since Oct 2007
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

Your pseudocode is a great start!

Four things:

(1) You need to not simply write "Enter the secret word", but also store it.

(2) The last if clause can come outside the loop, since if guess the secret word, then the loop will exit ("fall through").

(3) All variables need to be initialized. This would be easy to catch in the code, since Python would complain the first time you tried to check "misses < 6"

(4) There is no need for the guess a letter outside the loop.

So we might tweak it like this:

Python Syntax (Toggle Plain Text)
  1. get secret word
  2. initialize misses to 0
  3. initialize guess to "_"*len(secret word)
  4. while misses is less than 6 and guess is not equal to secret word
  5. write guess a letter
  6. if letter guessed is in secret word, then
  7. add letter to display and replace underline
  8. else: increase misses by 1
  9. print display
  10. if letters guessed equals secret word
  11. print congratulations, you got the secret word
  12. else: print sorry

As you turn the pseudo-code into code, this will get refined.
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

Now about functions:

Think of a function as a dedicated servant. You "call" the servant to fetch you a burger("cheese", "ketchup", "lettuce", "medium-well"), and the servant returns the burger to you.

So here's an example relevant to your code:

Python Syntax (Toggle Plain Text)
  1. # create the function -- this code gets stored, but not executed.
  2. def new_display(secret_word, old_guess, letter):
  3.  
  4. # flip the secret word and the guess: turn A into _ in secret word and _ into A in guess.
  5. while True:
  6. if letter in secret_word:
  7. index = secret_word.find(letter)
  8. secret_word = secret_word.replace(letter, "_",1)
  9. old_guess = old_guess[:index]+letter+old_guess[index+1:]
  10. else:
  11. break
  12. return old_guess
  13.  
  14. # call the function for testing purposes
  15. # initialize variables
  16. misses = 0
  17. guess = "_E__E_"
  18. secret = "LETTER"
  19.  
  20. # call the function with single letter
  21. letter = "R"
  22. guess = new_display(secret, guess, letter)
  23.  
  24. # check the output
  25. if guess == "_E__ER":
  26. print "R: Test passed"
  27. else:
  28. print "R: Test failed"
  29.  
  30. # call again with double letter
  31. letter = "T"
  32. guess = new_display(secret, guess, letter)
  33.  
  34. # check output
  35. if guess == "_ETTER":
  36. print "T: Test passed"
  37. else:
  38. print "T: Test failed"
  39.  
  40. # call with letter not in puzzle
  41. letter = "Z"
  42. guess = new_display(secret, guess, letter)
  43.  
  44. # check output
  45. if guess == "_ETTER":
  46. print "Z: Test passed"
  47. else:
  48. print "Z: Test failed"

This is not necessarily the most elegant way to code the new_display, but it illustrates some things.

First, note that when the function is *defined*, nothing happens ... except that the code for the function is stored in a location labeled "new_display". Note that if you later make a variable called "new_display", it will clobber the function! :lol:

Second, note that we call the function from the main code itself. You can call functions from within other functions as well. But for beginning projects, the usual plan is

def fn1
def fn2

main code calls fn1 and fn2 as needed


Third, note that the "arguments" (your prof may use the term "parameters") of the function are the values that the main code must supply to the servant in order for the servant to do his job. In this case, the servant needs to know the secret word, the current guess, and the guessed letter.

Fourth, note that the return value (at the end of the function, although functions can also return from the middle if an early exit is needed) is the command to our servant to bring back the requested result.

Fifth, note that our servant has but one job to do: to run through the secret word, and fill in any corresponding position in the guess with the letter given. He doesn't print stuff; he doesn't update the number of misses; he only replaces _ with letter.

So now, having tasked our servant with this one job, we call him anytime we need his service.

Sixth, notice that any scratch work the servant does is lost when the function returns. You can see in the definition of new_display() that I have the line secret_word = secret_word.replace(letter, "_",1). You might think that this would cause the secret_word to get changed permanently in the main code. But actually, the function receives a copy of the secret_word, and when the function returns, all of its variables "go out of scope" -- that is, are forgotten.

This is why the return value is so important. It is the only result that the main code will ever see from the function.* The changes to old_guess that happen within the body of new_display() are not kept; this is why when the main code calls new_display(), it has to clobber guess with the return value: guess = new_display(secret, guess, letter); otherwise, those changes will be lost.

Does that help clear things up?

Jeff

* Not true for mutable objects like lists, but that's another story.
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

There's so much info that I'm getting confused. From the code I have above, I still don't know why secret is not defined in this code:

python Syntax (Toggle Plain Text)
  1. #stuff the first person sees
  2. def get_secret(secret):
  3. """Get the secret word/phrase"""
  4. secret = raw_input(secret)
  5.  
  6. misses = 0
  7. guess = "_ "*len(secret)
  8. print guess
  9. #Stuff the second person sees
  10. def do_turn(display,misses):
  11. """
  12. Display the current status for the user and let them make a guess.
  13. """
  14.  
  15. guess = raw_input("What letter would you like to guess?")
  16. while misses < 6 and guess!=secret:
  17.  
  18. for i in range(len(secret)):
  19. if guess != secret[i]:
  20. misses = misses +1
  21. print str(misses)
  22. display = "_ " * len(secret)
  23. print display
  24.  
  25. guess = get_secret(secret)
  26. print guess
  27.  
  28.  
  29. letter = do_turn(display,misses)
  30. print letter

I kind of understand what you're saying, but isn't "secret" stored in the function get_secret? so when i type guess = "_"*len(secret), isn't secret defined? This might be asking for too much, but do you think you can fix/delete whatever is wrong with my code right now so I can kind of start fresh. Everytime I get frustrated, I can't seem to think and this program is due tomorrow night (no sleep for me). I'll keep working on it, and if I figure it out, i'll post the updated code. Thanks again!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Eclipse77 is offline Offline
13 posts
since Oct 2007
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

Sorry for the overload. Your code is improving.

Here's a walkthrough of your code up to the error:

lines 2-4: the function get_secret is defined. No code is executed yet; no variables are defined.

line 6: misses is set to 0

line 7: guess is set to "_" * len( ... wait, there is no variable called secret.

So you will definitely have to call get_secret before you try to set guess.

Two more issues, and then it'll work.

(1) get_secret() should not take secret as a parameter, since our servant should not have to know the secret in order to get the secret!

(2) get_secret() will have to return the secret in order for your main code to receive it. Watch the difference here:

Python Syntax (Toggle Plain Text)
  1. ## BAD ##
  2. >>> def get_secret():
  3. """Get the secret word/phrase"""
  4. secret = raw_input("Enter the secret word: ")
  5.  
  6. >>> misses = 0
  7. >>> get_secret()
  8. Enter the secret word: phlerm
  9. >>> guess = "_"*len(secret)
  10.  
  11. Traceback (most recent call last):
  12. File "<pyshell#8>", line 1, in <module>
  13. guess = "_"*len(secret)
  14. NameError: name 'secret' is not defined
  15. >>>


Why the error? Because the variable 'secret' is defined within the function get_secret. It is a local variable; it is in the "namespace" of get_secret(). When get_secret() returns, all of the local variables "go out of scope" -- are forgotten. That is, our servant's scratchwork is thrown away.

So the remedy is to return the important result:

Python Syntax (Toggle Plain Text)
  1. ## GOOD ##
  2. >>> def get_secret():
  3. secret = raw_input("Enter the secret word: ")
  4. return secret # <<< 1
  5.  
  6. >>> misses = 0
  7. >>> my_secret = get_secret() # <<< 2
  8. Enter the secret word: phlerm
  9. >>> guess = "-"*len(my_secret)
  10. >>> print guess
  11. ------
  12. >>> print my_secret
  13. phlerm
  14. >>>

In the line marked <<< 1, the function returns the necessary value. This is its only means of communicating with the outside code.

In the line marked <<< 2, the main code calls the function and stores the return value in my_secret. This is the only means that the main code has of communicating with the function.

So the key is: all of the variables inside the function are private, or "local". The only connection the function has with the outside world is receiving parameters (when called) and returning a value back to the caller.

So here's the modified pair of functions:

Python Syntax (Toggle Plain Text)
  1. # Define all your functions FIRST before the main code.
  2.  
  3. #stuff the first person sees
  4. def get_secret():
  5. """Get the secret word/phrase"""
  6. secret = raw_input("Enter the secret word: ")
  7. return secret
  8.  
  9. #Stuff the second person sees
  10. # This function was trying to do the whole game. Your prof's directions gave you
  11. # the design for this function. It does one thing: get the user's guess.
  12. def do_turn(display, misses):
  13. """
  14. Display the current status for the user and let them make a guess.
  15. """
  16. print display
  17. print "You have missed %d times." % misses
  18.  
  19. guess = raw_input("What letter do you guess? ")
  20. return guess
  21.  
  22. misses = 0
  23. secret = get_secret()
  24. print secret
  25.  
  26. display = "-"*len(secret)
  27. letter = do_turn(display,misses)
  28. print letter

Hope it helps,
Jeff
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Oct 20th, 2007
0

Re: newbie in need of help for hangman game

So this is what I have now. I wanted to use your loop for replacing the underscores, but I don't think I was taught that complexity. Is there a way to replace the underscores using a different method in new_display?

Here's are the 2 codes for comparison, but unfortunately mine doesn't work.

#1
python Syntax (Toggle Plain Text)
  1. # Define all your functions FIRST before the main code.
  2. #stuff the first person sees
  3. def get_secret():
  4. """Get the secret word/phrase"""
  5. secret = raw_input("Enter the secret word: ")
  6. return secret
  7.  
  8.  
  9. #Stuff the second person sees
  10. # This function was trying to do the whole game. Your prof's directions gave you
  11. # the design for this function. It does one thing: get the user's guess.
  12. def do_turn(display, misses):
  13. """
  14. Display the current status for the user and let them make a guess.
  15. """
  16. return display
  17. print "You have missed %d times." % misses
  18.  
  19.  
  20.  
  21. #This is where we can update the letters guessed
  22. def new_display(secret, display, guess):
  23. """Displays the replacement of underscores with letters that the user has guessed"""
  24. misses = 0
  25. while True:
  26. if guess in secret:
  27. index = secret.find(guess)
  28. secret = secret.replace(letter, "_",1)
  29. display = display[:index]+guess+display[index+1:]
  30. else:
  31. misses = misses+1
  32. return secret,display
  33.  
  34. misses = 0
  35. secret = get_secret()
  36. print secret
  37.  
  38. display = "-"*len(secret)
  39. letter = do_turn(display,misses)
  40. print letter
  41.  
  42. secret,display = new_display(secret,display,guess)
  43. print secret,display

#2
python Syntax (Toggle Plain Text)
  1. # Define all your functions FIRST before the main code.
  2. #stuff the first person sees
  3. def get_secret():
  4. """Get the secret word/phrase"""
  5. secret = raw_input("Enter the secret word: ")
  6. return secret
  7.  
  8.  
  9. #Stuff the second person sees
  10. # This function was trying to do the whole game. Your prof's directions gave you
  11. # the design for this function. It does one thing: get the user's guess.
  12. def do_turn(display, misses):
  13. """
  14. Display the current status for the user and let them make a guess.
  15. """
  16. return display
  17. print "You have missed %d times." % misses
  18.  
  19.  
  20.  
  21. #This is where we can update the letters guessed
  22. def new_display(secret, display, guess):
  23. """Displays the replacement of underscores with letters that the user has guessed"""
  24. misses = 0
  25. while True:
  26. for i in range (len(secret)):
  27. if secret[i] == guess:
  28. print guess
  29. else:
  30. misses = misses+1
  31. return secret,display
  32.  
  33. misses = 0
  34. secret = get_secret()
  35. print secret
  36.  
  37. display = "-"*len(secret)
  38. letter = do_turn(display,misses)
  39. print letter
  40.  
  41. secret,display = new_display(secret,display,guess)
  42. print secret,display

I know when i used len(secret), secret isn't defined and so I don't know how to scan the letters for the secret way back in the first function.

Now I wish I knew some programming before coming to this course. Anyways, thanks for all your help Jeff. Much appreciated.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Eclipse77 is offline Offline
13 posts
since Oct 2007
Oct 21st, 2007
0

Re: newbie in need of help for hangman game

Not a problem. It's worth it to have people come back and say "It worked! I learned something!"

Let's focus on the new_display function and walk through it

Python Syntax (Toggle Plain Text)
  1. #This is where we can update the letters guessed
  2. def new_display(secret, display, guess):
  3. """Displays the replacement of underscores with letters that the user has guessed"""
  4. misses = 0
  5. while True:
  6. for i in range (len(secret)):
  7. if secret[i] == guess:
  8. print guess
  9. else:
  10. misses = misses+1
  11. return secret,display

So imagine dispatching the function and saying, "Here's the secret word 'phlerm', the current display '------', and the guess 'e'."

At line 4, misses is set to 0. This is NOT the same variable as 'misses' in the main code, because it is inside the function. It is a local variable.

At line 5, we begin the loop. Since the condition will never be false, we'll need to break or return out of the loop somewhere...

At line 6, we begin a for-loop. Since our secret word is 'phlerm', the range(len(secret) is [0,1,2,3,4,5], so we have "for i in [0,1,2,3,4,5]:"

At line 7, we check secret[i] against 'e' and print it if it is. This will work out like this:

i screen
0
1
2
3 e
4
5

otherwise (line 10), misses += 1. So by the time the for loop is done, there will be an e on the screen and misses will be 5.

And then, because we're done with the for loop, the while loop now executes again ... printing another e and bringing misses up to 10. And then....

You get the idea. This was definitely not what you had in mind. For one thing, the display variable never gets updated. For another, you didn't want to print stuff on the screen.

So what did you have in mind? Write a plan for new_display(). NOTICE that new_display() does not have the responsibility of keeping track of the misses. That's not its job!

Jeff
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Oct 21st, 2007
0

Re: newbie in need of help for hangman game

so where in the code should i update misses or display misses? should it be in the function do_turn because that's where teh display gets updated?

i suppose my plan is that while True, if the letter is guessed correctly, it will scan the letters in secret and if it matches, the letter guessed would replace the underscore. the loops still continues until misses are less than 6 or until letters guessed is equal to the secret word. also, for each correct guess, the misses should not increase, therefore i should create an if,elif, else block?

I guess what i'm also confused about are where the variables should be, inside the function or part of the main code.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Eclipse77 is offline Offline
13 posts
since Oct 2007

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: Syntax errorL can not assign to a function call
Next Thread in Python Forum Timeline: Adding 1 with 1 in binary





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC