3
votes

I am creating a simple Hangman implementation for a school project and I am currently stuck on the task of making a letter reveal itself in the word when guessed correctly. I already have code that generates blank spaces depending on the number of letters in the word, as well as pretty much every other component of the game I need, but I can't figure out how to replace spaces with correct letters.

I'd appreciate it if you kept it simple and explained as I'm still rather new at programming. And if possible, so that I don't have to change up my code too much.

Here's my code:

import random

name = str(input("What's your name?"))
print("Hello,", name + "!")
failures = 0
allowed = 1
guessed = str()
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog',
            'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito',
            'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam' 'mario', 'parachute', 'agario', 'obama',
            'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating',
            'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon',
            'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn', name]

def correct(guess):
    if guess in word:
        if guess not in guessed:
            print("Correct")
            return(True)
    else:
        if guess not in word and len(guess) == 1 and guess in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ':
            if guess not in guessed:
                print("Incorrect!")
                return(False)

print("Guess this word!")
print("You can input any letter from A to Z and the space key.")
wordnumber = random.randint(0, len(wordlist))
word = (wordlist[wordnumber])
print("_ "*len(word))
while failures < allowed:
    guess = str(input("Guess a letter!"))
    if len(guess) != 1 or guess not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ':
        print("That is not a letter, try again.")
    if guess in guessed:
        print("You have already guessed that letter, try again.")
    iscorrect = correct(guess)
    guessed = guessed, guess
    if iscorrect == True:
        print("Word display still in development")
    if iscorrect == False:
        print("You suck")
        failures = failures+1
        print("You have", allowed , "guesses left.")
    if failures == allowed:
        replay = str(input("Press 1 to play again, press 2 to exit."))
        if replay == 1:
            break
        else:
            quit()

#Now all I have to do is find a way to display positions of correct letters.
4
It would be easier if you can give just what string you have,what you want to replace,what would be d output instead of the whole program - vks
The reason I gave my entire code is so that we could work out an answer that doesn't shake up the code. Anyway, the string that I have is wordnumber = random.randint(0, len(wordlist)) word = (wordlist[wordnumber]) print("_ "*len(word)) - ahjfcshfghb
If I knew how to format that that would be great xD - ahjfcshfghb
Welcome, new user! If you're satisfied with my answer, please accept it and upvote it. - Michael Laszlo

4 Answers

0
votes

To find where the letter in the string, use word.index(guess). Afterwards replace the letter in in the "blanks" word. To do so save b_word = "_ "*len(word), And replace '_' in the correct place:

s = list(b_word)
s[word.index(guess)] = guess

After that print the new b_word.

0
votes

To help you display the guessed letters, you can keep track of them in a list in which letters that haven't been guessed yet are represented by underscores (or blanks or whatever you like).

You can initialize such a list as soon as you have decided on the secret word:

guessed_letters = len(word) * ['_']

To display the guessed letters, join them with spaces:

print(' '.join(guessed_letters))

Subsequently, when the user enters a letter guess, you can update the correctly guessed letters by enumerating over the word:

for position, letter in enumerate(word):
    if letter == guess:
        guessed_letters[position] = letter

I have revised your program to incorporate this code:

import random

name = str(input("What's your name?"))
print("Hello,", name + "!")
failures = 0
allowed = 1
guessed = str()
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog',
            'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito',
            'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam' 'mario', 'parachute', 'agario', 'obama',
            'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating',
            'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon',
            'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn', name]

def correct(guess):
    if guess in word:
        if guess not in guessed:
            print("Correct")
            return(True)
    else:
        if guess not in word and len(guess) == 1 and guess in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ':
            if guess not in guessed:
                print("Incorrect!")
                return(False)

print("Guess this word!")
print("You can input any letter from A to Z and the space key.")
wordnumber = random.randint(0, len(wordlist))
word = (wordlist[wordnumber])
guessed_letters = len(word) * ['_']
print(' '.join(guessed_letters))
while failures < allowed:
    guess = str(input("Guess a letter!"))
    if len(guess) != 1 or guess not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ':
        print("That is not a letter, try again.")
    if guess in guessed:
        print("You have already guessed that letter, try again.")
    iscorrect = correct(guess)
    guessed = guessed, guess
    if iscorrect == True:
        for position, letter in enumerate(word):
          if letter == guess:
            guessed_letters[position] = letter
        print(' '.join(guessed_letters))
    if iscorrect == False:
        print("You suck")
        failures = failures+1
        print("You have", allowed , "guesses left.")
    if failures == allowed:
        replay = str(input("Press 1 to play again, press 2 to exit."))
        if replay == 1:
            break
        else:
            quit()

There are other problems with the program that fall outside the scope of this question.

0
votes
import sys
import random
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog',
            'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito',
            'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam', 'mario', 'parachute', 'agario', 'obama',
            'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating',
            'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon',
            'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn']

class Guess:

    def __init__(self):

        self.SECRET = random.choice(wordlist)
        self.GUESSES_ALLOWED = int(raw_input("The secret's word has %s letter, you how many times can you be mistaken?" % len(self.SECRET)))
        self.WRONG = []
        self.GUESSED = []

    def make_a_guess(self):

        while self.GUESSES_ALLOWED:
            current_guess = raw_input('Guess a letter!')   # TODO: to check for double chars
            self.print_mask()

            if current_guess in self.GUESSED:
                print "You;ve already guessed that! Try again!\n"
                self.make_a_guess()
                self.print_mask()
            elif current_guess in self.WRONG:
                print "You;ve already guessed that! Try again!\n"
                self.make_a_guess()
                self.print_mask()
            elif current_guess not in self.SECRET:
                self.GUESSES_ALLOWED -= 1
                print "WRONG! Guesses left: %s\n" % self.GUESSES_ALLOWED
                self.WRONG.append(current_guess)
                self.print_mask()
            elif current_guess in self.SECRET:
                print "CORRECT! Guesses left: %s\n" % self.GUESSES_ALLOWED
                self.GUESSED.append(current_guess)
                self.print_mask()
                if set(self.GUESSED) == set(self.SECRET):
                    print "You guessed the word!"
                    repeat = raw_input("Play again? type y or n and press Enter")
                    if 'y' in repeat:
                        a = Guess()
                        a.make_a_guess()
                    elif 'n' in repeat:
                        sys.exit(0)
        else:
            print "You got '%s' guesses left, you lost!" % self.GUESSES_ALLOWED
            repeat = raw_input("Play again? type y or n and press Enter")
            if 'y' in repeat:
                a = Guess()
                a.make_a_guess()
            elif 'n' in repeat:
                sys.exit(0)


    def print_mask(self):

        guessed_indexes = []
        for letter in self.GUESSED:
            indexes_for_one_letter = [i for i, x in enumerate(self.SECRET) if x == letter]
            guessed_indexes += indexes_for_one_letter

        MASK_TO_PRINT = []
        for i, letter in enumerate(self.SECRET):
            if i in guessed_indexes:
                MASK_TO_PRINT.append(letter)
            else:
                MASK_TO_PRINT.append("_")

        print " ".join(MASK_TO_PRINT)


if __name__ == '__main__':

    game = Guess()
    game.make_a_guess()

Firstly, we import sys do we could exit if player does not want to play anymore

the whole logic is implemented in make_a_guess method of class Guess. everytime new game will be started, new instance of class Guess will be created.

This is a new implementation, because your variant had some really important errors, for instance, you'd better use raw_input() in order to autoconvert input to string.

In order to write you progress of guessing, print_mask() in my code is used in the method you should look for all of the occurencies of already guessed letters and gather them. For example, you guessed M and F and their indexes will be [0,3] if 'FORM' word is a secret word. That is why when you iterate in a loop over the secret word, if you meet that current index you iterate over can also be found in [0,3], -> that is when you add the letter for the corresponding index to some empty list you prepare for later print as a display of current progress. If no current index can be found in [0,3] during the iteration over the secret's word letters- then you add "_" instead of letter that was guessed to you prepared empty list.

Then you shrink the list to be as string in order to further print it: " ".join(MASK_TO_PRINT)

Logic is like that: secret word is 'cabage' you guessed 'c' before and 'a' so self.GUESSED contains [0,1,3] then you iterate over:

prepared_list_for_print = []
for i, letter in enumerate('cabage'):
    if i in [0,1,3]:
        prepared_list_for_print.append(letter)
    else:
        prepared_list_for_print.append("_")
0
votes

Your instructions to the player are a bit misleading: you tell the player that they can "input any letter from A to Z and the space key", but you don't mention that they can also use the lower case letters from a to z, and that's important because your program distinguishes between upper & lower case letters.

Various things could be done to your code to improve it. Eg, you don't need to convert the data returned by input() to a string - it's already a string. You could simplify the logic in testing whether a guess is valid: you perform some of your tests twice on the same input data. Also, your replay logic needs a bit of work. And there's no builtin function named quit() (and you haven't defined one); maybe you meant exit(), but you can probably reorganize your logic so you don't need to use exit().

Anyway, here's a way to implement a Hangman word display function. This function receives the word string and guessed, which could be a string or a list, but it would be more efficient to use a set.

def display(word, guessed):
    word = ' '.join([ch if ch in guessed else '_' for ch in word])
    print(word)


display('computer', set('stop'))
display('cabbage', list('bag'))
display('banana', 'abcn')            

output

_ o _ p _ t _ _
_ a b b a g _
b a n a n a