Brett
Brett

Reputation: 13

I need help fixing this hangman function

Okay, so I am stuck at this part in my code. When I want the letter that the user guesses to replace that letter in the string of underscores, it replaces every single letter with that letter. I don't know what to do. Here is the code.

 def hangman(secret):
    '''
    '''

    guessCount = 7
    w = '_'*len(secret)

    while guessCount > 0:
        guess = input('Guess: ')
        if guess in secret:
            indices = indexes(secret, guess)
            print(indices)
            for i in range(len(indices)):
                w = w.replace(w[indices[i]],secret[indices[i]])
                print(w)
        else:
            guessCount = guessCount - 1
            print('Incorrect.',guessCount,'incorrect guesses remaining.')

Any help in pointing out what I can do specifically in line 9 and 10 would be greatly appreciated.

Here is the first function that I defined earlier that I use in this function.

def indexes(word, letter):
    '''returns a list of indexes at which character letter appears in word'
    '''

    indices = []

    for i in range(len(word)):
        if letter in word[i]:
            indices.append(i)
    return indices

Upvotes: 1

Views: 118

Answers (4)

lightalchemist
lightalchemist

Reputation: 10221

Strings are immutable in Python. Hence, it is not a suitable data structure for representing your word. In my opinion, Kyle Friedline's approach is probably the right way.

def hangman(secret, guessCount=7):
    assert guessCount > 0  # Never really good to hard code magic numbers.

    w = ['_'] * len(secret)  # Make 'w' a list instead because list is mutable
    while guessCount > 0:
        guess = input("Guess: ")
        if guess in secret:
            indices = indexes(secret, guess)  # I'm guessing indexes is defined elsewhere?
            for i in indices:
                w[i] = guess  # Make it explicit. secret[i] == guess anyway.
            print("".join(w))  # Join w into a word
        else:
            guessCount -= 1  # More concise
            print("Incorrect. ", guessCount, " incorrect guesses remaining.")

A little suggestion for implementing indexes:

def indexes(word, letter):
    return [i for i, c in enumerate(word) if c == letter]

Or simply replace the call to indexes() with:

indices = [i for i, c in enumerate(secret) if c == guess]

Upvotes: 0

Kyle Friedline
Kyle Friedline

Reputation: 11

What is happening is that line 10 is thinking that you want to replace "_" with "guess". Instead:

for i in indices:
  w = list(w)
  w[i] = guess
  w = ''.join(w)
  print(w)

There is most likely a more elegant way of doing this rather than changing w from string to list and from list back to string again, but I can't think of it off the top of my head.

Upvotes: 1

TessellatingHeckler
TessellatingHeckler

Reputation: 29003

Where you have w[indices[i]] whatever the index number you use, w contains _ there. Because of that, you always do something like: w.replace('_', 'e') and:

>>> help("".replace)

Help on built-in function replace:

replace(...)
    S.replace(old, new[, count]) -> string

    Return a copy of string S with all occurrences of substring
    old replaced by new.

So you get:

>>> "_____".replace('_', 'e')
'eeeee'

@Vaiska makes another good point, you are counting through the length of indices, not the indices themselves. So you are always counting 0,1,2,3...

@Kyle Friedline has one solution, another would be to build up a new string taking one character at a time, either from the guess or from the secret, depending on whether you were at an index point or not.

Upvotes: 0

vaisakh
vaisakh

Reputation: 1031

Modify the loop to iterate through the contents of indices:

for i in indices:
    w = w.replace(w[indices[i]],secret[indices[i]])
print(w)

Otherwise, the loop will execute from 0 to the length of the indices array since range was mentioned. Also, you may probably want to move the print statement outside the for loop.

Upvotes: 1

Related Questions