Reputation: 503
I'm trying to create a little game.
The rules are very straightforward: you give an English word, and the computer will try to guess this word letter by letter.
The thing is, I'm trying to make the computer guess the letters in a smart way. Let me give you a simple example of what I'm trying to build so you can understand:
You give the word "cat" to the computer to guess.
The 130K words list I have is narrowed to only the words who have 3 characters, which makes up to 805 words only. And from this list of words, an alphabet is created, containing only 25 letters (not the whole 26) because the new 805 words list contains all the letters of the alphabet but the "z". So we now have a list containing 25 (different) letters.
-- As I can't upload anything here on SO, we will say for this example that the massive 130K words list is a 10 words list (variable name "fullDice") --
If you try to run my code, pick a word from inside this list or else it's not going to work
The computer now guesses a random letter from this 25 letters list.
If the letter is not in the word, he doesn't do anything and re-guess a letter from the list.
But if the letter is in the word, that's where things become more complicated. Let's say the computer guess the letter "c". I want the computer to re-narrow the possible words list, to only those having a "c" in the first character. That way, the 805-words list become now an only 36 words list. Because there are only 36 words who are 3 characters and starts with a "c", a new alphabet is created. And the new alphabet is now made of only 14 letters, making it easier for the computer to guess the next letter and be correct about it. And so on until he finds all the letters.
I'm stuck on part 5. If you try to run my code just below, you'll see that the dictionnary list is never narrowed. That's my problem.
import time
from random import randint
fullDice = ["panda", "tiger", "cat", "elephant", "whale", "leopard", "gorilla", "fish", "snake", "eagle"]
askForWord = input("Please enter an english word: ")
while True:
updatedDice = []
for k in range (0, len(fullDice)):
if len(askForWord) == len(fullDice[k]):
updatedDice += [fullDice[k]]
alphabet = []
for i in range (0, len(updatedDice)):
for n in range (0, len(updatedDice[i])):
if updatedDice[i][n] not in alphabet:
alphabet += [updatedDice[i][n]]
guessRandomLetter = alphabet[randint(0, len(alphabet) - 1)]
print("I guess the letter: " + guessRandomLetter)
print("From this dice: " + str(len(updatedDice)))
print("From this amount of letters: " + str(len(alphabet)) + "\n")
time.sleep(0.75)
guessedWordUnderlined = "_" * len(askForWord)
if guessRandomLetter in askForWord:
for m in range(0, len(askForWord)):
if askForWord[m] == guessRandomLetter: # CHECKING IF THE GUESSED LETTER IS INSIDE THE WORD
guessedWordUnderlined = list(guessedWordUnderlined)
guessedWordUnderlined[m] = guessRandomLetter
guessedWordUnderlined = ''.join(map(str, guessedWordUnderlined))
if guessedWordUnderlined == askForWord: # CHECK IF USER HAS WON
print("YOU WON")
break
Upvotes: 2
Views: 1473
Reputation: 101
Having reviewed your code again, I believe the problem is in the statement guessedWordUnderlined = "_" * len(askForWord)
. This creates a string of underscores whose length is equal to that of askFOrWord
. The problem is that each at each iteration of the while True:
loop, a new string. This means that at each iteration, the string becomes a list of underscores with one correct letter, but in the next iteration it is overridden. To fix this, you should move the line guessedWordUnderlined = "_" * len(askForWord)
from its current location to directly below askForWord = input("Please enter an english word: ")
. This will mean that it is present in the global scope rather than the local scope, meaning it won't get overwritten. You should also put the line global guessedWordUnderlined
at the beginning of the while
loop, if I'm not mistaken. This may require you to rework some code. Hope this works for you!
Upvotes: 0
Reputation: 101
I believe the problem is that if guessedWordUnderlined in askForWord
will never be true. The in
operator tests whether the first operator is within the second argument, which is a container, such as a list or string. "_" * len(askForWord)
, the value of guessedWordUnderlined
, is a string of underscores, and you are testing whether or not that is in askForWOrd
. If the vale of askForWord
is cat
, askForWord
can be thought of as ["c", "a", "t"]
, so the in operator will be testing "___" == "c" or "___" == "a" or "___" == "t"
, none of which will be true. This means that the code beneath it will never execute, so the code just repeats forever, randomly guessing letters within the word. I cannot really tell what the function of this if
is, as you already know each letter you could have chosen is in askForWord
, though I'm sure I'm missing something obvious.
As an aside, you frequently use a construction similar to for x in range(0, len(LIST): ... LIST[x]
, which can be more concisely and obviously written as for x in LIST: ... x
. For example, your code
for k in range (0, len(fullDice)):
if len(askForWord) == len(fullDice[k]):
updatedDice += [fullDice[k]]
alphabet = []
could be written as
for k in fullDice:
if len(askForWord) == len(k):
updatedDice += [k] # This should be updatedDice.append(k), but I
# have left it as-is for simplicity's sake.
alphabet = []
which should help your code become more readable. There are a few other edits that could be made to make your code more pythonic, but aside from that line I cannot see anything functionally wrong with it. If you share what this if
is supposed to help, it might make it a bit easier to find any other errors in your code. I hope this helps, and good luck!
Upvotes: 0
Reputation: 84
you just asked a qs including that code. i tryed to make it work only with the available words in the dictionnary you gave as "python".
from random import randint
import random
import time
import datetime
random.seed(datetime.datetime.now())
wordOfTheUser = input("ENTER ENGLISH WORD HERE: ")
if wordOfTheUser in ("abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"):
pass
else:
print("your word is not on the list, still devlopping.")
raise
diceList1 = ["abracadabra", "python", "coding", "soup", "paper", "list", "leader", "program", "software", "eating","abcdefghigklmnopqrstuvwxyz"]
diceList2 = []
for k in range (0, len(diceList1) - 1):
if len(diceList1[k]) == len(wordOfTheUser):
diceList2 += [diceList1[k]]
makeAlphabet = []
for b in range (0, len(diceList2)):
for x in range (0, len(diceList2[b])):
if diceList2[b][x] not in makeAlphabet:
makeAlphabet += [diceList2[b][x]]
computerWordSize = "_" * int(len(wordOfTheUser))
a= len(makeAlphabet)
while True:
try:
randomIndex = randint(0, a)
except ValueError:
randomIndex = randint(0, a)
pass
try:
letterChosenRandomly = makeAlphabet[randomIndex]
except IndexError as e:
try:
randomIndex = randint(0, int(len(makeAlphabet)))
letterChosenRandomly = makeAlphabet[randomIndex]
except:
pass
print("I guess the letter -> " + letterChosenRandomly)
diceList3 = []
if letterChosenRandomly in wordOfTheUser:
print("\n=== WON ===> " + letterChosenRandomly)
print("=== ALPHABET ===> " + str(len(makeAlphabet)))
print("=== HDW1 ===> " + str(len(diceList1)))
print("=== hdw2 ===> " + str(len(diceList2)))
print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
k=-1
makeAlphabet = []
for i in range (0, len(wordOfTheUser) ):
if letterChosenRandomly == wordOfTheUser[i]:
computerWordSize = list(computerWordSize)
computerWordSize[i] = letterChosenRandomly
for l in range (0, len(diceList2)):
if computerWordSize[i] == diceList2[l][i]:
diceList3 += [diceList2[l]]
for d in range(0, len(diceList3)):
for h in range(0, len(diceList2[b])):
if diceList2[d][h] not in makeAlphabet:
makeAlphabet += [diceList2[d][h]]
won = False
computerWordSize = ''.join(map(str, computerWordSize))
print(computerWordSize)
if computerWordSize == wordOfTheUser:
won = True
if won is True:
print("YOU WON")
break
time.sleep(1)
else:
print("\n=== LOOSE ===> " + letterChosenRandomly)
print("=== ALPHABET ===> " + str(len(makeAlphabet)))
print("=== HDW1 ===> " + str(len(diceList1)))
print("== hdw2 ===> " + str(len(diceList2)))
print("=== hdw3 ===> " + str(len(diceList3)) + "\n\n")
try:
makeAlphabet.remove(letterChosenRandomly)
except:
print ("Letters not in list")
break
k=0
diceList3 = []
for q in range (0, len(wordOfTheUser) - 1):
for l in range(0, len(diceList2)):
if computerWordSize[q] == diceList2[l][q]:
diceList3 += [diceList2[l]]
for d in range(0, len(diceList3)):
for h in range(0, len(diceList2[b])):
try:
if diceList2[d][h] not in makeAlphabet:
makeAlphabet += [diceList2[d][h]]
except:
try:
for s in range(0, len(diceList3)):
for f in range(0, len(diceList2)):
if diceList2[s][f] not in makeAlphabet:
makeAlphabet += [diceList2[s][f]]
except:
("your word is too short")
time.sleep(1)
Upvotes: 0