Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python hangman help
#1
Hello.

I need some help with my code. It has to be in the format I am posting. So when I run the game, it is basically supposed to keep asking for a guess until the number of guess reach 0 or until the word is found. Number of guesses start at 4 and decrease every single time the player inputs a wrong guess. The program is supposed to recognize repeated guesses of the same letter as a wrong guess. If the player guesses a letter correctly, the corresponding _ in the blanks are replaced with the letter, even if there are multiple occurrences of that letter within the word. If the player guesses all letters correctly and number of guesses is greater than 0, then the player wins. I have posted my code below. I think the problem is in the update_puzzle_string() block as it is updating the "temp" variable to give me the blanks with the word filled in. Please review it and let me know what I am doing wrong. All help is appreciated Smile

import random

def main():

    

    # Display Instructions

    instruction_list = ['Keep guessing letters until your guesses run out']

    x = 0

    y = 0

    instructions(instruction_list)

    

    #Display Puzzle String

    word = 'apple'

    blanks = (' _ '*len(word))

    display_puzzle_string(blanks)

    

    #Play Game

    num_guess = 4

    guess = ''

    guessed_letters = []

    temp = ''

    word_found = False

    correct_guess = ''

    play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess)

    

    

    #Display Result

    display_result(word_found, num_guess, word)

    

    #End Game

    end_game()

	

	

def instructions(instruction_list):

    # Display Instructions

    for instruction in instruction_list:

        print(instruction)

        

        

def display_puzzle_string(blanks):

    print('The answer so far is: '+ blanks)

    return blanks



def play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess):

    while num_guess>0 and word_found == False:

        guess = get_guess(num_guess)

        update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters)

        guessed_letters += guess

        update_num_guess(correct_guess, num_guess)

        display_updated_puzzle(temp)

        is_word_found(temp)

    return word_found

        

        

        

def get_guess(num_guess):

    guess = input('Guess a letter (You have ' + str(num_guess) + ' guesses remaining): ')    

    return guess





def update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters):

    for count, item in enumerate(word):

            if item == guess and item != guessed_letters:

                correct_guess = True

                temp += guess

            else:

                correct_guess = False

                temp += blanks[count]

                

            return temp

    

def update_num_guess(correct_guess,num_guess):

    if correct_guess == True:

        num_guess = num_guess

    else:

        num_guess += 1

        

    

def display_updated_puzzle(temp):

    print('The answer so far is: ' + ''.join(temp))



    

def is_word_found(temp):

    if ' _ ' in temp:

        word_found = False

    else:

        word_found = True 

    

    return word_found 

    

def display_result(word_found, num_guess, word):

    if word_found == True:

        print('Good job! You found the word' + word)

                   

    elif num_guess==0:

        print('Not quite, the correct word was ' + word+'.Better luck next time')

                   



def end_game():

    input('Press enter to end the game')

    

    



main()    

(Feb-12-2019, 07:17 PM)A1395 Wrote: this one is wrong. The temp gives an empty value. It does not update. The input letter does not seem to register with the program. What could be wrong?
Hello.

I need some help with my code. It has to be in the format I am posting. So when I run the game, it is basically supposed to keep asking for a guess until the number of guess reach 0 or until the word is found. Number of guesses start at 4 and decrease every single time the player inputs a wrong guess. The program is supposed to recognize repeated guesses of the same letter as a wrong guess. If the player guesses a letter correctly, the corresponding _ in the blanks are replaced with the letter, even if there are multiple occurrences of that letter within the word. If the player guesses all letters correctly and number of guesses is greater than 0, then the player wins. I have posted my code below. I think the problem is in the update_puzzle_string() block as it is updating the "temp" variable to give me the blanks with the word filled in. Please review it and let me know what I am doing wrong. All help is appreciated Smile

import random

def main():

    

    # Display Instructions

    instruction_list = ['Keep guessing letters until your guesses run out']

    x = 0

    y = 0

    instructions(instruction_list)

    

    #Display Puzzle String

    word = 'apple'

    blanks = (' _ '*len(word))

    display_puzzle_string(blanks)

    

    #Play Game

    num_guess = 4

    guess = ''

    guessed_letters = []

    temp = ''

    word_found = False

    correct_guess = ''

    play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess)

    

    

    #Display Result

    display_result(word_found, num_guess, word)

    

    #End Game

    end_game()

	

	

def instructions(instruction_list):

    # Display Instructions

    for instruction in instruction_list:

        print(instruction)

        

        

def display_puzzle_string(blanks):

    print('The answer so far is: '+ blanks)

    return blanks



def play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess):

    while num_guess>0 and word_found == False:

        guess = get_guess(num_guess)

        update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters)

        guessed_letters += guess

        update_num_guess(correct_guess, num_guess)

        display_updated_puzzle(temp)

        is_word_found(temp)

    return word_found

        

        

        

def get_guess(num_guess):

    guess = input('Guess a letter (You have ' + str(num_guess) + ' guesses remaining): ')    

    return guess





def update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters):

    for count, item in enumerate(word):

            if item == guess and item != guessed_letters:

                correct_guess = True

                temp += guess

            else:

                correct_guess = False

                temp += blanks[count]

                

            return temp

    

def update_num_guess(correct_guess,num_guess):

    if correct_guess == True:

        num_guess = num_guess

    else:

        num_guess += 1

        

    

def display_updated_puzzle(temp):

    print('The answer so far is: ' + ''.join(temp))



    

def is_word_found(temp):

    if ' _ ' in temp:

        word_found = False

    else:

        word_found = True 

    

    return word_found 

    

def display_result(word_found, num_guess, word):

    if word_found == True:

        print('Good job! You found the word' + word)

                   

    elif num_guess==0:

        print('Not quite, the correct word was ' + word+'.Better luck next time')

                   



def end_game():

    input('Press enter to end the game')

    

    



main()    
Reply
#2
Just to start with, update_puzzle_string is a mess. item is going to be a string, but guessed_letters is a list. So item is never going to be equal to guessed_letters. You probably want 'not in' there instead of '!='.

You want to start with correct_guess as False, and only set it to True when there is a correct_guess. As you are doing it now, you are setting it to False for each non-matching letter, so if you have a correct guess that is not the last letter, correct_guess is False. But this doesn't really matter, because you are not doing anything with correct_guess.

When the letter is incorrect you pull a character from the blanks string. But the blanks string has three character for each letter in the word, not one, And since it's always the same characters, why not just insert those three characters?

You are returning temp too soon. As it is, you return (and end the function) after checking the first letter. You want to check at the end of the loop after checking all letters, so you need to unindent the return statement to be even with the for loop.

Even if all of that is fixed, you are only adding the new letters to temp, you are erasing any letters that were guessed in previous turns. So your if condition should probably be if item == guess or item in guessed_letters:. In fact, if you just add guess to guessed letters, you could just do the second part of that or.

Back where you call update_puzzle_string in main, you don't assign the return value to anything. So temp never changes in main.

There are still other problems with your code, but that seems like plenty for a start.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Thank you for the help Ichabod. I took your advice and tried to fix the code as much as I could. Please note that the word for this game is supposed to be different every time it is run. I just put 'apple' there because it would be easiest.

Whenever the player provides a correct input, number of guesses remain the same. A correct input is defined as a letter within the word that HAS NOT been input before. Each time a letter is correctly chosen, the puzzle string is supposed to become updated. The puzzle is supposed to show each guessed letter in the corresponding place.

Right now with the code as it is, when I input a correct guess the number of guesses decrease. The puzzle string does update with the letter in the correct place BUT as soon as a new letter is input, it updates a completely new string as opposed to working on the string we were previously using. I want one output for temp that is updated every single time a letter is correctly guessed instead of a new entire string being added each time. Please take a look at it and let me know what I can do to fix it. I am not sure how to solve this problem. I believe the problems would be in the update_puzzle_string function and the udpdate_num_guess function

import random





def main():

    

    # Display Instructions

    instruction_list = ['Keep guessing letters until your guesses run out']

    instructions(instruction_list)

    

    #Display Puzzle String

    word = 'apple'

    blanks = ('_'*len(word))

    display_puzzle_string(blanks)

    

    #Play Game

    num_guess = 4

    guess = ''

    guessed_letters = []

    temp = ''

    word_found = False

    correct_guess = False

    play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess)

    

    

    #Display Result

    display_result(word_found, num_guess, word)

    

    #End Game

    end_game()

	

	

def instructions(instruction_list):

    # Display Instructions

    for instruction in instruction_list:

        print(instruction)

        

        

def display_puzzle_string(blanks):

    print('The answer so far is: '+ blanks)

    return blanks



def play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess):

    while num_guess>0 and word_found == False:

        guess = get_guess(num_guess)

        temp = update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters)

        guessed_letters += guess

        num_guess = update_num_guess(correct_guess, num_guess)

        display_updated_puzzle(temp)

        is_word_found(temp)

    return word_found

        

        

        

def get_guess(num_guess):

    guess = input('Guess a letter (You have ' + str(num_guess) + ' guesses remaining): ')    

    return guess





def update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters):

    for count, item in enumerate(word):

            if item == guess:

                if item not in guessed_letters:

                    correct_guess = True

                    temp += guess

            else:

                temp += blanks[count]

            

                

                    

    return temp

    

def update_num_guess(correct_guess,num_guess):

    if correct_guess == True:

        num_guess = num_guess

    else:

        num_guess += -1

        

    return num_guess

        

    

def display_updated_puzzle(temp):

    print('The answer so far is: ' + ''.join(temp))



    

def is_word_found(temp):

    if ' _ ' in temp:

        word_found = False

    else:

        word_found = True 

    

    return word_found 

    

def display_result(word_found, num_guess, word):

    if word_found == True:

        print('Good job! You found the word' + word)

                   

    elif num_guess==0:

        print('Not quite, the correct word was ' + word+'.Better luck next time')

                   



def end_game():

    input('Press enter to end the game')

    

    



main()
Reply
#4
You need to return correct_guess from update_puzzle_string along with temp. You do that with a tuple: return temp, correct_guess, and then tuple assignment for the call: temp, correct_guess = update_puzzle_string(...). Note that you are not initializing correct_guess to False at the beginning of update_puzzle_string. You need to do that or the first correct guess will make all guesses after it appear to be correct.

Also note that you are still wiping out previous correct guesses. I would change the blanks[count] on line 131 to temp[count]. That way if they've guessed that letter already it will stay in temp. Also note that temp is growing each turn. I would short circuit that by reinitializing temp to an empty string at the start of update_puzzle_string.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
(Feb-12-2019, 11:39 PM)ichabod801 Wrote: Also note that you are still wiping out previous correct guesses. I would change the blanks[count] on line 131 to temp[count]. That way if they've guessed that letter already it will stay in temp. Also note that temp is growing each turn. I would short circuit that by reinitializing temp to an empty string at the start of update_puzzle_string.

Thank you so much for the help.

I realize that I am wiping out previous correct guesses. I need to stop temp from growing, and from erasing previous correct guesses. For example, if I guess a it should be a____. And then if I guess p, I want app__ returned. And then if I guess q, it should just be app__. Right now if I guess a, I get a____. And then if I guess p, I get a_______pp____ because as the function repeats, the temp keeps getting longer. Any way around this problem?
Reply
#6
(Feb-13-2019, 12:15 AM)A1395 Wrote: Any way around this problem?

That's what I was talking about in my last post. Although thinking about it, what I said wouldn't work. Start a new_temp variable as an empty string at the start of update_puzzle string. Add to that instead of to temp. In the else clause, pull from temp instead of blank. Return new_temp instead of temp.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
(Feb-13-2019, 03:12 AM)ichabod801 Wrote:
(Feb-13-2019, 12:15 AM)A1395 Wrote: Any way around this problem?

That's what I was talking about in my last post. Although thinking about it, what I said wouldn't work. Start a new_temp variable as an empty string at the start of update_puzzle string. Add to that instead of to temp. In the else clause, pull from temp instead of blank. Return new_temp instead of temp.

I am getting an erorr if I try to pull from temp instead of blank. 'String index out of range' is the erorr. Also, the new_temp variable also does not work for me. I need the puzzle string to update like a____,app___,appl_ ...

As I understand it, right now what is happening is that every time I input a letter the letter is being added to the string a____ but every single time an input is executed, a new temp string is added to the old temp string. So it elongates the string instead of overwriting the old one. It shows as a______pp____ if I type in p. What would I do to overwrite the old string and update it as explained? And what would I do to make sure that if a letter is wrongly guessed, the temp string is not overwritten but is the same as the last temp?

Here is the latest version of the code

import random





def main():

    

    # Display Instructions

    instruction_list = ['Keep guessing letters until your guesses run out']

    instructions(instruction_list)

    

    #Display Puzzle String

    word = 'apple'

    blanks = ('_'*len(word))

    display_puzzle_string(blanks)

    

    #Play Game

    num_guess = 4

    guess = ''

    guessed_letters = []

    temp = ''

    word_found = False

    correct_guess=''

    play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess)

    

    

    #Display Result

    display_result(word_found, num_guess, word)

    

    #End Game

    end_game()

	

	

def instructions(instruction_list):

    # Display Instructions

    for instruction in instruction_list:

        print(instruction)

        

        

def display_puzzle_string(blanks):

    print('The answer so far is: '+ blanks)

    return blanks



def play_game(num_guess, guessed_letters, temp, word_found, blanks, word, correct_guess):

    while num_guess>0 and word_found == False:

        correct_guess = False

        guess = get_guess(num_guess)

        temp, correct_guess = update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters)

        guessed_letters += guess

        num_guess = update_num_guess(correct_guess, num_guess)

        display_updated_puzzle(temp)

        is_word_found(temp)

    return word_found

        

        

        

def get_guess(num_guess):

    guess = input('Guess a letter (You have ' + str(num_guess) + ' guesses remaining): ')    

    return guess





def update_puzzle_string(blanks, temp, word, correct_guess, guess, guessed_letters):

    for count, item in enumerate(word):

            if item == guess:

                if item not in guessed_letters:

                    correct_guess = True

                    temp += guess

            else:

                temp += blanks[count]

                           

    return temp, correct_guess

    

def update_num_guess(correct_guess,num_guess):

    if correct_guess == True:

        num_guess = num_guess

    else:

        num_guess += -1

        

    return num_guess

        

    

def display_updated_puzzle(temp):

    print('The answer so far is: ' + ''.join(temp))



    

def is_word_found(temp):

    if ' _ ' in temp:

        word_found = False

    else:

        word_found = True 

    

    return word_found 

    

def display_result(word_found, num_guess, word):

    if word_found == True:

        print('Good job! You found the word' + word)

                   

    elif num_guess==0:

        print('Not quite, the correct word was ' + word+'.Better luck next time')

                   



def end_game():

    input('Press enter to end the game')

main()    
Reply
#8
Overwriting temp would be a real pain, because strings can't really be overwritten. You would have to build a new string from three parts, every step of the way. That's why I suggested the new_temp variable.

Show me what you've tried with the new_temp variable and drawing from temp instead of blanks, and exactly what error you are getting.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#9
So this is the code I was using for new_temp

def update_puzzle_string(temp, word, correct_guess, guess, guessed_letters):

    new_temp = ''

    for count, item in enumerate(word):

            if item == guess:

                if item not in guessed_letters:

                    correct_guess = True

                    new_temp += guess

            else:

                new_temp += temp[count]

                           

    return new_temp, correct_guess
The error returned is:

IndexError: string index out of range
Reply
#10
I see the problem. The temp variable is initialized to '' in main. You should initialize it to all blanks ('_' * len(word)).

You are going to have another problem here, however. If they guess the same letter twice, and it's a valid letter, nothing gets added to new temp. I would combine the two if conditions with and, to make sure it always adds a letter.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python Hangman Game - Multiple Letters Problem t0rn 4 4,531 Jun-05-2020, 11:27 AM
Last Post: t0rn
  Hangman metro17 4 2,969 Sep-18-2019, 10:59 AM
Last Post: perfringo
  Trouble coding hangman Tay 1 2,330 Mar-28-2019, 01:57 AM
Last Post: ichabod801
  Hangman code problem KrakowKid 1 2,370 Feb-25-2019, 06:29 PM
Last Post: ichabod801
  Hangman 2skywalkers 3 60,400 Oct-19-2018, 01:49 PM
Last Post: ichabod801
  Hangman Help. 2skywalkers 4 4,127 Jun-26-2018, 02:49 AM
Last Post: ichabod801
  Python Hangman Replacing "_" with letters. 2skywalkers 6 11,976 Jun-25-2018, 12:01 PM
Last Post: gruntfutuk
  Simple Hangman Game Issue andrew95 2 4,304 Apr-02-2018, 02:24 PM
Last Post: andrew95
  Designing Hangman game spacetimeguy 2 5,083 Feb-02-2018, 08:55 PM
Last Post: spacetimeguy
  TKinter Hangman Game Bumble 1 20,297 Jul-19-2017, 06:56 PM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020