I know there are already countless clones of Wordle. Nevertheless I try to program my own version.
In the function is_real_word it should be checked whether the entered word of the user occurs in the word list. If so, the variable check = True.
However, the FOR loop is always exited when the counter is at 1.
The file "5_letter_words.txt" contains 3 entries: wetter, wolle, watte
And last but not least also the return value for eingabewort is sometimes NONE. And I don't know why?
import random
def word_list():
wordle = []
with open("5_letter_words.txt", "r") as file:
for line in file:
myTuple = line.strip()
wordle.append(myTuple)
return wordle
def random_word(wordlist):
return random.choice(wordlist)
def is_real_word(guess, wordlist):
for word in wordlist:
if guess == word:
return True
return False
def check_guess(guess, randomword):
randomword_tuple = []
guess_tuple = []
length = len(randomword)
output = ["-"] * length
for index in range(length):
if guess[index] == randomword[index]:
output[index] = "X"
randomword = randomword.replace(guess[index], "-", 1)
for index in range(length):
if guess[index] in randomword and output[index] == "-":
output[index] = "O"
randomword = randomword.replace(guess[index], "-", 1)
return ''.join(output)
def next_guess(wordlist):
guess = input('Please enter a guess: ')
guess = guess.lower()
valid = is_real_word(guess, wordlist)
if valid == False:
print('Thats not a real word!')
next_guess(wordlist)
else:
return guess
def play():
target = []
target = word_list()
zufallswort = str()
zufallswort = random_word(target)
eingabewort = next_guess(target)
print('Eingabewort: ', eingabewort)
print('Zielwort: ', zufallswort)
play()
Could you check if your function word_list returns the list?
You dont give a clear path, only the file name.
If it works, try:
def is_real_word(guess, wordlist):
for word in wordlist:
if guess == word:
check = 1
break
return check
Explanation
I am currently writing a code that simulates a game of hangman, but cheats by attempting to evade the player's guesses by changing the word. The class and methods are defined in hangman.py, while play_hangman.py calls the instance of Hangman and the play method (cannot be changed per the instructions of the assignment).
Problem
In the play method, I received the following error: "
TypeError: askForWordLength() takes 1 positional argument but 2 were given "
I know that this means I am giving too many arguments into the call of the method, but I am unsure of how to change it. I have tried rewriting the 5th line of the following code multiple times to fix this error, but it does not cease:
Specific Section of Code*
def play(self):
MODE = 1
openSession = 1
while(openSession == 1):
word_length = self.askForWordLength(self.words)
num_guesses = self.askForNumOfGuesses()
wordStatus = self.wordStatus(word_length)
letters_already_guessed = []
print()
gameOver = 0
while (gameOver == 0):
if (MODE == 1):
self.printCountOfRemainingWords(self.remainingWords)
self.printGameStats(self.remainingWords. letters_already_guessed,
self.num_guesses, self.wordStatus)
guess = self.askPlayerForGuess(letters_already_guessed)
letters_already_guessed.append(guess)
num_guesses -= 1
remainingWords = self.retrieveRemainingWords(guess, self.remainingWords,
num_guesses, word_length)
wordStatus = self.wordStatus(remainingWords[0], letters_already_guessed)
print()
if (guess in wordStatus):
num_guesses += 1
if ('-' not in wordStatus):
game_over = 1
print('Congratulations! You won!')
print('Your word was: ' + wordStatus)
if (num_guesses == 0 and game_over == 0):
game_over = 1
print('Haha! You Lose')
print('Your word was: ' + remainingWords[0])
print('Thanks for playing Hangman!')
ENTIRE CODE
hangman.py
import re
class Hangman:
# hangman self method
def hangman(self):
self.hangman = Hangman() # object of the Hangman class
def words(self):
with open('dictionary.txt') as file: # opens dictionary text file
file_lines = file.read().splitlines() # reads and splits each line
all_words = [] # empty list to contain all words
valid_words = [] # empty list to contain all valid words
for word in file_lines: # traverses all words in the file lines
if len(word) >= 3: # accepts word if it has at least 3 letters
all_words.append(word) # appends accepted word to list
# list of all invalid characters in python
CHARACTERS = ["~", "`", "!", "#", "#", "$", "%", "^", "&", "*", "(",
")", "-", "_", "=", "+", "[", "]", "{", "}", "|", "\","
"", "'", "?", "/", ">", ".", "<", ",", "", ";", ":"]
for i in CHARACTERS: # traverse list of invalids
for word in all_words:
if i not in word: # if invalid character is not in word
valid_words.append(word) # accept and append to list
return valid_words # return list of valid words
def askForWordLength(self, valid_words):
word_lengths = [] # empty list for possible word lengths
for word in valid_words: # traverse list of valid words
length = word.__len__() # record length of current word
if (length not in word_lengths):
word_lengths.append(length) # accept and append to list
word_lengths.sort()
# inform user of possible word lengths
print('The available word lengths are: ' + str(word_lengths[0]) + '-'
+ str(word_lengths[-1]))
print()
# have user choose from possible word lengths
while(1):
try:
length = int(input('Please enter the word length you want: '))
if (length in word_lengths):
return length
except ValueError:
print('Your input is invalid!. Please use a valid input!')
print()
def askForNumberOfGuesses(self):
while(1):
try:
num_guesses = int(input('Enter number of guesses you want: '))
if (num_guesses >= 3):
return num_guesses
except ValueError:
print('Your input is invalid!. Please use a valid input!')
print()
def wordStatus(self, length):
status = '-'
for i in range(0, length):
status += '-'
return
def remainingWords(self, file_lines, length):
words = []
for word in file_lines:
if (word.__len__() == length):
words.append(word)
return words
def printGameStats(self, letters_guessed, status, num_guesses):
print('Game Status: ' + str(status))
print()
print('Attempted Guesses' + str(letters_guessed))
print('Remaining Guesses' + str(num_guesses))
def askPlayerForGuess(self, letters_guessed):
letter = str(input('Guess a letter: ')).lower()
pattern = re.compile("^[a-z]{1}$")
invalid_guess = letter in letters_guessed or re.match(pattern, letter) == None
if (invalid_guess):
while (1):
print()
if (re.match(pattern, letter) == None):
print('Invalid guess. Please enter a correct character!')
if (letter in letters_guessed):
print('\nYou already guessed that letter' + letter)
letter = str(input('Please guess a letter: '))
valid_guess = letter not in letters_guessed and re.match(pattern, letter) != None
if (valid_guess):
return letter
return letter
def retrieveWordStatus(self, word_family, letters_already_guessed):
status = ''
for letter in word_family:
if (letter in letters_already_guessed):
status += letter
else:
status += '-'
return status
def retrieveRemainingWords(self, guess, num_guesses, remaining_words,
wordStatus, guesses_num, word_length,
createWordFamiliesDict,
findHighestCountWordFamily,
generateListOfWords):
word_families = createWordFamiliesDict(remaining_words, guess)
family_return = wordStatus(word_length)
avoid_guess = num_guesses == 0 and family_return in word_families
if (avoid_guess):
family_return = wordStatus(word_length)
else:
family_return = findHighestCountWordFamily(word_families)
words = generateListOfWords(remaining_words, guess, family_return)
return words
def createWordFamiliesDict(self, remainingWords, guess):
wordFamilies = dict()
for word in remainingWords:
status = ''
for letter in word:
if (letter == guess):
status += guess
else:
status += '-'
if (status not in wordFamilies):
wordFamilies[status] = 1
else:
wordFamilies[status] = wordFamilies[status] + 1
return wordFamilies
def generateListOfWords(self, remainingWords, guess, familyToReturn):
words = []
for word in remainingWords:
word_family = ''
for letter in word:
if (letter == guess):
word_family += guess
else:
word_family += '-'
if (word_family == familyToReturn):
words.append(word)
return words
def findHighestCountWordFamily(self, wordFamilies):
familyToReturn = ''
maxCount = 0
for word_family in wordFamilies:
if wordFamilies[word_family] > maxCount:
maxCount = wordFamilies[word_family]
familyToReturn = word_family
return familyToReturn
def printCountOfRemainingWords(self, remainingWords):
show_remain_words = str(input('Want to view the remaining words?: '))
if (show_remain_words == 'yes'):
print('Remaining words: ' + str(len(remainingWords)))
else:
print()
def play(self, askForWordLength, askForNumberOfGuesses, remainingWords,
words, wordStatus, printCountOfRemainingWords, printGameStats,
askPlayerForGuess, retrieveRemainingWords):
MODE = 1
openSession = 1
while (openSession == 1):
word_length = askForWordLength(words)
num_guesses = askForNumberOfGuesses()
wordStatus = wordStatus(word_length)
letters_already_guessed = []
print()
game_over = 0
while (game_over == 0):
if (MODE == 1):
printCountOfRemainingWords(remainingWords)
printGameStats(remainingWords, letters_already_guessed,
num_guesses, wordStatus)
guess = askPlayerForGuess(letters_already_guessed)
letters_already_guessed.append(guess)
num_guesses -= 1
remainingWords = retrieveRemainingWords(guess, remainingWords,
num_guesses, word_length)
wordStatus = wordStatus(remainingWords[0], letters_already_guessed)
print()
if (guess in wordStatus):
num_guesses += 1
if ('-' not in wordStatus):
game_over = 1
print('Congratulations! You won!')
print('Your word was: ' + wordStatus)
if (num_guesses == 0 and game_over == 0):
game_over = 1
print('Haha! You Lose')
print('Your word was: ' + remainingWords[0])
print('Thanks for playing Hangman!')```
It looks like you don't understand how classes work or there is a piece of code not shown here. When you define a method in a class, the first argument always refers to the object on which the method operates, which is conventionally called self. Any subsequent arguments are defined how you want. Usually, you don't need to pass the first self argument because it is passed according to the object you use. Any remaining arguments are your responsibility though.
For example:
class Student:
def __init__(self, name, age):
# Initializer (Commonly called Constructor in other languages)
# This is the first method that will run when you create an object and
# it runs automatically (You don't need to call it).
# This is where you'd initialize the state of the object, for example:
# Create a student with name and age.
# name and age are regular parameters of the __init__ method. We'd like
# to save them as attributes of our student object which is represented
# by self.
self.name = name
self.age = age
# Maybe we'd like to save a list of grades too
self.grades = []
def add_grade(self, grade):
# self is our object, and grade is the parameter
self.grades.append(grade)
def get_average(self):
# If we don't need additional parameters, we don't have to, but self is
# mandatory
return sum(self.grades) / len(self.grades)
def print_status(self):
# Note I am calling get_average() and I don't specify self. It's determined automatically.
print("Name:", self.name)
print("Age:", self.age)
print("Average:", self.get_average())
# We created the class, but we need to create some objects to use it.
s1 = Student("Dan", 15)
s2 = Student("Maya", 14)
# Note we only pass the custom parameters we specified which are `grade`
# self is determined by the object we are using (s1 or s2)
s1.add_grade(81)
s1.add_grade(86)
s2.add_grade(89)
s2.add_grade(93)
s1.print_status()
s2.print_status()
I hope this example helps you understand how methods work. In your code, I don't understand why you pass the methods as arguments of the play method and I don't see where you call this method or where you even create a Hangman object, so I can't help further.
I'm writing a hangman game and found a code online for replacing blank spaces with the letters after a correct guess was made but it unfortunately produces a 'NoneType' error
I'm not sure how to correct it and I haven't been able to apply other answers I've found online to the code to fix it
word_list = ['around','august','branch','bright','castle','change','across']
tries = 0
word = random.choice(word_list)
print(word)
blank = print ("_ "*len(word))
while tries < 7:
guess = input("Enter a letter: ")
blank = list(blank)
for k in range(0, len(word)) or []:
if guess == word[k]:
blank[k] = guess
print (''.join(blank))
You are storing the return of print and not the value in print into blank
Try this :
import random
word_list = ['around','august','branch','bright','castle','change','across']
tries = 0
word = random.choice(word_list)
print(word)
blank = "_ "*len(word) #storing what you want in variable
print(blank) #print the variable
while tries < 7:
guess = input("Enter a letter: ")
blank = list(blank) #here you do list() on the variable and not the return of print >> OK
for k in range(0, len(word)) or []:
if guess == word[k]:
blank[k] = guess
print (''.join(blank))
I'm very new to python and I'm trying to make a hangman game. I currently have a line of code saying word = (random.choice(open("Level1py.txt").readline())).
I'm getting the error 'str' object does not support item assignment.
Here is the rest of my code (sorry for the mess):
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word[word.index(c)] = '*'
print(guess_word)
word = (random.choice(open("Level1py.txt").readline().split()))
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Strings are immutable in python. An easy workaround is to use lists, which are mutable:
st = "hello"
ls = list(st)
ls[3] = 'r'
st = ''.join(ls)
print(st)
Outputs
helro
Edit: here's how you would implement it in your own code
import random
def checkLetter(letter, word, guess_word):
for c in word:
if c == letter:
guess_word[word.index(c)] = c
word_list = list(word)
word_list[word.index(c)] = "*"
word = ''.join(word_list)
print(guess_word)
word = 'test'
guess_word = ['_' for x in word]
print(guess_word)
while '_' in guess_word:
guess = input('Letter: ')
print(checkLetter(guess, word, guess_word))
Note that there are still other issues that have nothing to do with this, like printing None and duplicate printing
You can also solve your problem using a dictionary:
word = "my string" #replace this with your random word
guess_word = {i: '_' for i in set(word)} # initially assign _ to all unique letters
guess_word[' '] = ' ' # exclude white space from the game
wrong_attempts = 0
while '_' in guess_word.values():
guess = input('Letter: ')
if guess in guess_word.keys():
guess_word[guess] = guess
else:
wrong_attempts += 1
if wrong_attempts > 11:
break
printable = [guess_word[i] for i in word]
print(' '.join(printable))
if '_' in guess_word.values():
print('you lost')
else:
print('congratulation, you won')
I need to remove all excess white space and leave one space, between my words while only using if and while statements. and then state the amount of characters that have been removed and the new sentence
edit, it must also work for punctuation included within the sentence.
This is what I have come up with however it leaves me with only the first letter of the sentence i choose as both the number, and the final sentence. can anyone Help.
def cleanupstring(S):
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
else:
lasti = i
result += i
return result
sentence = input("Enter a string: ")
outputList = cleanupstring(sentence)
print("A total of", outputList[1], "characters have been removed from your string.")
print("The new string is:", outputList[0])
Your code should be something like this:
def cleanupstring(S):
counter = 0
lasti = ""
result = ""
for i in S:
if lasti == " " and i == " ":
i = ""
counter += 1
else:
lasti = i
result += i
return result, counter
sentence = input("Enter a string: ")
outputList = cleanupstring(sentence)
print("A total of", outputList[1], "characters have been removed from your string.")
print("The new string is:", outputList[0])
The counter keeps track of how often you remove a character and your [0] and [1] work now the way you want them to.
This is because outputList is now a tuple, the first value at index 0 is now the result and the second value at index 1 is the counter.