I can't understand the logic issue in my wordle game

140 Views Asked by At

So my task is to create a wordle game which would ask the user a word and in the output shows word with marked letters, just letters and uppercase letters.It shows marked letters(y*) - if this letter is in the word to guess, uppercase letters if letter in the word and in the right place and just letter if this letter is not in the word.

The problem is that when the word to guess is "vigor" and i'm writing "rover", in the output, I get r* o* v* e R. But I should get r o* v* e R, because it's only one "r" in this word and it's on the right place.

I have tryed to change location of the else's in letter_finder function and to add more conditions, but only made it worse. I feel like the answer is very simple, but i'm thinking in wrong direction, so here is my code:

hidden_word = "vigor"
print(hidden_word)

user_word = input("Guess the word: ")

answer_list = []


def letter_finder():
    mistakes = 0

    for letter_in_hidden, letter_in_user in zip(hidden_word, user_word):
        if hidden_word == user_word:
            print("You win!")
            break

        # print(letter_in_hidden, letter_in_user)
        elif letter_in_user in hidden_word and letter_in_user == letter_in_hidden:
            answer_list.append(letter_in_user.upper())
            " ".join(answer_list)

        elif letter_in_user in hidden_word:
            answer_list.append(letter_in_user + "*")
            " ".join(answer_list)

        elif letter_in_user not in hidden_word:
            answer_list.append(letter_in_user)
            " ".join(answer_list) + "."
        # elif letter_in_user == letter_in_hidden:

        elif user_word != hidden_word:
            mistakes += 1
            answer_list.clear()

        elif mistakes == 6:
            break

    print(" ".join(answer_list))
    answer_list.clear()


counter = 0
while hidden_word != user_word:
    letter_finder()
    user_word = str(input("Guess the word: "))
    counter += 1
    if counter == 5:
        print(f"Sorry, you lose. The answer is: {hidden_word}")
        break
2

There are 2 best solutions below

0
On

I would probably start by casting both words to proper lists so we can index them. This also has the advantage that we don't modify hidden_word directly.

Then I would process the words twice. Once to find and process exact matches and a second time to find and process partial matches.

def get_match(user_word, hidden_word):
    ## ---------------
    # covert to proper list and is now a copy
    ## ---------------
    hidden_word = list(hidden_word)
    user_word = list(user_word)
    ## ---------------

    ## -----------------
    ## find exact matches and take them out of future matchs
    ## -----------------
    for index, (u, h) in enumerate(zip(user_word, hidden_word)):
        if u == h:
            user_word[index] = u.upper()
            hidden_word[index] = "_"
    ## -----------------

    ## -----------------
    ## find non-exact matches and take them out of future matchs
    ## -----------------
    for index, u in enumerate(user_word):
        if u in hidden_word:
            user_word[index] += "*"
            hidden_word[hidden_word.index(u)] = "_"
    ## -----------------

    return user_word

hidden_word = "vigor"

user_word = "rover"
print(hidden_word, user_word, get_match(user_word, hidden_word))

user_word = "rigor"
print(hidden_word, user_word, get_match(user_word, hidden_word))

user_word = "vigor"
print(hidden_word, user_word, get_match(user_word, hidden_word))

Should return:

vigor rover ['r', 'o*', 'v*', 'e', 'R']
vigor rigor ['r', 'I', 'G', 'O', 'R']
vigor vigor ['V', 'I', 'G', 'O', 'R']
3
On

I believe this is what you're looking for:

from collections import defaultdict 

def check_answer(user_input, hidden_word, hidden_word_letter_count):
    if len(user_input)!=len(hidden_word):
        return f"your guess must contain {len(hidden_word)} letters!"
    copy = hidden_word_letter_count.copy()
    output = ['']*len(hidden_word)
    non_matching_indices = []
    for i in range(len(hidden_word)):
        if user_input[i] == hidden_word[i]:
            output[i] = user_input[i].upper()
            copy[user_input[i]]-=1
        else:
            non_matching_indices.append(i)
    for i in non_matching_indices:
        if user_input[i] != hidden_word[i]:
            if copy[user_input[i]]>0:
                output[i]=f"{user_input[i]}*"
                copy[user_input[i]]-=1
            else:
                output[i]=user_input[i].lower()
    return ''.join(output)


hidden_word = "vigor"
allowed_guesses = 5

hidden_word_letter_count = defaultdict(lambda: 0)
for letter in hidden_word:
    hidden_word_letter_count[letter]+=1

wrong_guesses = 0
while wrong_guesses < allowed_guesses:
    guess = input("Guess the word: ")
    if guess == hidden_word:
        print("You win!")
        break
    else:
        print(check_answer(guess,hidden_word,hidden_word_letter_count))
        wrong_guesses += 1
if wrong_guesses==allowed_guesses:
    print(f"Sorry, you lose. The answer is: {hidden_word}")