-1

As a starting programmer I am currently working on a hangman project, in which the given letters must return every time. Therefore I would like to work with a list that returns with the by the player given letters. However, this gives me the following issue:

  File "Hangman.py", line 65, in <module>
    word_blank[i] = guess
TypeError: 'str' object does not support item assignment

This is for the following part of my code:

while game_on == 'yes':
    answer = select_word(selection)
    if answer != 'error123':
        word_blank = answer_form(answer)
        break

# start guessing letters
count = 1
guesses = []

while count <= 10:
    print(f'\n\nYour guess count:\t{count}')
    print(f'Your guesses:\t\t{guesses}')
    guess = input('Guess a letter: ').lower()
    count += 1
    guesses.append(guess)

    for i in range(0, len(answer)):
        if answer[i] == guess:
            word_blank[i] = guess
            break

    print(' '.join(word_blank))

print('\n\nGame over..')

With answer form being:

def answer_form(answer):
    word_blank = []
    word_blank.extend(answer)

    for i in range(0, len(word_blank)):
        word_blank[i] = '_'

    return(' '.join(word_blank))

I have checked various answers on Stack Overflow already, but unfortunately I cannot relate these well to my personal code. I felt the solution in this link came close, but unfortunately it has been without results. How should I improve my code to get rid of the error, while being able to stay within the loop to add all the guessed letters to word_blank[i]?

Marco
  • 33
  • 7
  • 1
    Where do you initialize word_blank? You need to show all the relevant code. – CupinaCoffee Aug 06 '18 at 23:39
  • 1
    Possible duplicate of [Change one character in a string?](https://stackoverflow.com/questions/1228299/change-one-character-in-a-string) – Lev Zakharov Aug 06 '18 at 23:39
  • @CupinaCoffee I added the parts where word_blank initializes and how it is constructed. – Marco Aug 07 '18 at 16:54
  • 1
    strings are immutable - meaing: you can not change them. You can create a new one, f.e. by slicing: `s = "abcdk"` and then `s = s[:-1]+""efghij" + s[-1]`. For your game, use a list of characters, you can manipulate them easier. – Patrick Artner Aug 07 '18 at 16:56

1 Answers1

0

Your def answer_form(answer): returns a joined list - making it a string. You can not modify strings, they are immutable (see f.e. Immutable vs Mutable types). You can however recreate them, f.e. by slicing or using them as list of characters. See Change one character in a string? for that.


You can simplify your hangman if you use sets. It is easier to print '_' for any character that was not guessed yet, then manipulating strings (and you avoid manipulating lists as well ;o):

data = ["hang","man","carrot","supercalifragilisticexpialidocious"]

# random.choice solver (I am lazy ;o) ) - set to False for human player
autosolve = True

import random
from string import ascii_lowercase 
aslow = set(ascii_lowercase) 

# what should the user guess? random choice from data
what = random.choice(data).lower()

# store the length and characters used in what instead of calculating each time
lwhat = len(what)
swhat = set(what)
# these letters where already guessed 
guessed = set()

# amount of tries reached, we quit when twice the amount of characters got tried
tries = 0
while True and tries < 2*lwhat:

    # use list comprehension to print _ if a char was not guessed yet, else print char
    print("The secret word is: ", ' '.join(x if x in guessed else "_" for x in what))

    # we are done if all characters of what are guessed 
    if swhat.issubset(guessed):
        print(f"You did it! It took you {tries} tries") 
        break

    if not autosolve: 
        guess = input("Guess one letter or the complete word:").lower() 
    else:
        guess = random.choice(list(aslow))
        print("Guess one letter or the complete word:", guess)
        aslow.remove(guess)

    lguess = len(guess)

    # only count 1-character and full word guesses
    if lguess not in (1,lwhat):
        print("1 letter or the while word, try again") 
        continue

    tries += 1
    # one character was guessed
    if lguess == 1:
        guessed.add(guess) # add to set and print some feedback
        if guess in what:  
            print("Correct.")
        else:
            print("beeeeeep - that was wrong.")

    # whole word was guessed
    elif guess == what:
        print(f"You did it! It took you {tries} tries") 
        break
else:
    print("Too many tries: try again later")

print("The end")

The win-condition is: the set of the word you look for is a subset of all guessed characters.

Output:

The secret word is:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Guess one letter or the complete word: s
Correct.
The secret word is:  s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: n
beeeeeep - that was wrong.
The secret word is:  s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: b
beeeeeep - that was wrong.
The secret word is:  s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: v
beeeeeep - that was wrong.
The secret word is:  s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: j
beeeeeep - that was wrong.
The secret word is:  s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: e
Correct.
The secret word is:  s _ _ e _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ e _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: q
beeeeeep - that was wrong.
The secret word is:  s _ _ e _ _ _ _ _ _ _ _ _ _ _ _ s _ _ _ e _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: g
Correct.
The secret word is:  s _ _ e _ _ _ _ _ _ _ _ g _ _ _ s _ _ _ e _ _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: x
Correct.
The secret word is:  s _ _ e _ _ _ _ _ _ _ _ g _ _ _ s _ _ _ e x _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: w
beeeeeep - that was wrong.
The secret word is:  s _ _ e _ _ _ _ _ _ _ _ g _ _ _ s _ _ _ e x _ _ _ _ _ _ _ _ _ _ _ s
Guess one letter or the complete word: u
Correct.
The secret word is:  s u _ e _ _ _ _ _ _ _ _ g _ _ _ s _ _ _ e x _ _ _ _ _ _ _ _ _ _ u s
Guess one letter or the complete word: o
Correct.
The secret word is:  s u _ e _ _ _ _ _ _ _ _ g _ _ _ s _ _ _ e x _ _ _ _ _ _ o _ _ o u s
Guess one letter or the complete word: t
Correct.
The secret word is:  s u _ e _ _ _ _ _ _ _ _ g _ _ _ s t _ _ e x _ _ _ _ _ _ o _ _ o u s
Guess one letter or the complete word: c
Correct.
The secret word is:  s u _ e _ c _ _ _ _ _ _ g _ _ _ s t _ c e x _ _ _ _ _ _ o c _ o u s
Guess one letter or the complete word: m
beeeeeep - that was wrong.
The secret word is:  s u _ e _ c _ _ _ _ _ _ g _ _ _ s t _ c e x _ _ _ _ _ _ o c _ o u s
Guess one letter or the complete word: h
beeeeeep - that was wrong.
The secret word is:  s u _ e _ c _ _ _ _ _ _ g _ _ _ s t _ c e x _ _ _ _ _ _ o c _ o u s
Guess one letter or the complete word: f
Correct.
The secret word is:  s u _ e _ c _ _ _ f _ _ g _ _ _ s t _ c e x _ _ _ _ _ _ o c _ o u s
Guess one letter or the complete word: i
Correct.
The secret word is:  s u _ e _ c _ _ i f _ _ g i _ i s t i c e x _ i _ _ i _ o c i o u s
Guess one letter or the complete word: k
beeeeeep - that was wrong.
The secret word is:  s u _ e _ c _ _ i f _ _ g i _ i s t i c e x _ i _ _ i _ o c i o u s
Guess one letter or the complete word: d
Correct.
The secret word is:  s u _ e _ c _ _ i f _ _ g i _ i s t i c e x _ i _ _ i d o c i o u s
Guess one letter or the complete word: y
beeeeeep - that was wrong.
The secret word is:  s u _ e _ c _ _ i f _ _ g i _ i s t i c e x _ i _ _ i d o c i o u s
Guess one letter or the complete word: a
Correct.
The secret word is:  s u _ e _ c a _ i f _ a g i _ i s t i c e x _ i a _ i d o c i o u s
Guess one letter or the complete word: r
Correct.
The secret word is:  s u _ e r c a _ i f r a g i _ i s t i c e x _ i a _ i d o c i o u s
Guess one letter or the complete word: p
Correct.
The secret word is:  s u p e r c a _ i f r a g i _ i s t i c e x p i a _ i d o c i o u s
Guess one letter or the complete word: l
Correct.
The secret word is:  s u p e r c a l i f r a g i l i s t i c e x p i a l i d o c i o u s
You did it! It took you 25 tries
The end

The "AI" is really bad for short words though:

The secret word is:  _ _ _ _ _ _
Guess one letter or the complete word: q
beeeeeep - that was wrong.
The secret word is:  _ _ _ _ _ _
Guess one letter or the complete word: v
beeeeeep - that was wrong.
The secret word is:  _ _ _ _ _ _
Guess one letter or the complete word: p
beeeeeep - that was wrong.
The secret word is:  _ _ _ _ _ _
Guess one letter or the complete word: o
Correct.
The secret word is:  _ _ _ _ o _
Guess one letter or the complete word: y
beeeeeep - that was wrong.
The secret word is:  _ _ _ _ o _
Guess one letter or the complete word: a
Correct.
The secret word is:  _ a _ _ o _
Guess one letter or the complete word: d
beeeeeep - that was wrong.
The secret word is:  _ a _ _ o _
Guess one letter or the complete word: w
beeeeeep - that was wrong.
The secret word is:  _ a _ _ o _
Guess one letter or the complete word: m
beeeeeep - that was wrong.
The secret word is:  _ a _ _ o _
Guess one letter or the complete word: i
beeeeeep - that was wrong.
The secret word is:  _ a _ _ o _
Guess one letter or the complete word: t
Correct.
The secret word is:  _ a _ _ o t
Guess one letter or the complete word: j
beeeeeep - that was wrong.
Too many tries: try again later
The end
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69