I am creating a hangman game and I am displaying the letters that have not yet been guessed so if no letters have been guessed it displays all the abc's. And what I am trying to figure out is how to get rid of the letter the user inputted from the letters remaining and return the string of the remaining letters.
def get_available_letters(letters_guessed):
"""
Returns a string of letters that have not yet been guessed.
:param: letters_guessed: letters that have been guessed so far by the player
:type letters_guessed: str
:return: letters that have not been guessed
:rtype: str
"""
ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
letters_guessed = letters_guessed.lower()
for ch in ALL_LETTERS:
if ch in letters_guessed:
letters_left = ALL_LETTERS.replace(letters_guessed, '')
return letters_left
else:
return ALL_LETTERS
CodePudding user response:
You don't need the else in the for loop, because as soon as a ch
is not in letters_guessed
you return the full list. Do this instead:
def get_available_letters(letters_guessed):
"""
Returns a string of letters that have not yet been guessed.
:param: letters_guessed: letters that have been guessed so far by the player
:type letters_guessed: str
:return: letters that have not been guessed
:rtype: str
"""
ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
letters_guessed = letters_guessed.lower()
for ch in ALL_LETTERS:
if ch in letters_guessed:
letters_left = ALL_LETTERS.replace(letters_guessed, '')
return letters_left
return ALL_LETTERS
CodePudding user response:
You can just subtract letters_guessed
from ALL_LETTERS
, the available letters remains.
This function returns the subtracted letters by replacing letters_guessed
in ALL_LETTERS
to be empty. So what remains is the remaining available letters.
def get_available_letters(letters_guessed):
ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
return ALL_LETTERS.replace(letters_guessed.lower(), '')
Example:
letters_guessed = "abc"
ALL_LETTERS.replace(letters_guessed, '')
# abc will be removed from abcdefghijklmnopqrstuvwxyz
# -> defghijklmnopqrstuwxyz
However, there are some edge cases.
letters_guessed
is not sorted, sincereplace
replaces the exact substring.- Some letters are not included in ALL_LETTERS, same reason.
This can be fixed by just looping letters_guessed
letters one by one and then removing then from ALL_LETTERS
def get_available_letters(letters_guessed):
ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
for letter in letters_guessed.lower():
ALL_LETTERS = ALL_LETTERS.replace(letter, '')
return ALL_LETTERS
- You can refactor your code so that
available_letters
is a variable outside of the function (either global or as a property of a class)
available_letters = 'abcdefghijklmnopqrstuvwxyz'
when a letter is guessed, just remove a letter from available_letters
CodePudding user response:
str.replace(old, new[, count])
repalces the old string with new string, not each character in the old string.
Example:
'abc'.replace('ba', '') # return 'abc', because string 'ba' is not in 'abc'
'abc'.replace('ab', '') # return 'c', string 'ab' is replaced with ''
Therefore, one solution is to iterate each character in the letters_guessed
, and replace it with the null character.
def get_available_letters(letters_guessed):
ALL_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
letters_guessed = letters_guessed.lower()
for ch in letters_guessed:
ALL_LETTERS = ALL_LETTERS.replace(ch, '')
return ALL_LETTERS
CodePudding user response:
This function returns a string with all the letters from abc
that are not in letters_guessed
.
def get_available_letters(letters_guessed):
abc = "abcdefghijklmnopqrstuvwxyz"
for ch in abc:
if ch in letters_guessed.lower():
abc = abc.replace(ch, "")
return abc
BTW, I recommend using lists instead of strings for cases such as this one.
Here's how this function could be written if lists were used:
def get_available_letters(letters_guessed):
abc = "abcdefghijklmnopqrstuvwxyz"
return [ch for ch in abc if ch not in letters_guessed.lower()]
CodePudding user response:
I think it is better to store available letters as a list and pop values out of it when player makes a guess. Have a look at this implementation.
from string import ascii_lowercase
ALL_LETTERS = list(ascii_lowercase)
LETTERS_LEFT = ALL_LETTERS
def guess():
letter = str(input("Enter letter: ")).lower()
if letter in LETTERS_LEFT:
LETTERS_LEFT.pop(LETTERS_LEFT.index(letter)) # Remove letter from list
elif letter in ALL_LETTERS:
print("This letter was already used!")
else:
print("Wrong input! Use one of:", "".join(ALL_LETTERS))
return get_available_letters()
def get_available_letters():
return LETTERS_LEFT
while True:
print(guess())
Actually I believe you should use all this stuff inside of a class, as OOP is better for game development (IMHO)