pythonprettytablecolorama

Custom Python Wordle game not showing colors correctly


from requests import get
from json import loads
from prettytable import PrettyTable
from colorama import Fore
from os import system


def select_game_word():
    """This function will return a random 5-letter word"""
    response = get("https://random-word-api.vercel.app/api?words=1&length=5")
    word = loads(response.text)[0].upper()

    return word


def verify_guessed_word(guessed_word):
    """This function will return a boolean value if the guessed word is verified or not"""

    if len(guessed_word) == 5:
        response = get(f"https://api.dictionaryapi.dev/api/v2/entries/en/{guessed_word}")

        if response.status_code == 200:
            return True

    return False


def ask_guessed_word():
    """This function will return the guessed word from the user"""

    guessed_word = input("Type in your word: ").upper()

    while not verify_guessed_word(guessed_word):
        print("Invalid word. Please try again.")
        guessed_word = input("Type in your word: ").upper()

    return guessed_word


def get_guessed_word_colors(guessed_word, selected_word):
    """This function will return a list of colors for each letter in the guessed word"""

    letter_index_pairs = [] # This list will store key-value pairs for the letters and their indexes.
    
    # Getting all the green letters from the word first
    
    for i in range(0, 5):
        if guessed_word[i] == selected_word[i]:
            selected_word = selected_word.replace(guessed_word[i], "-") # replacing the green letters to dashes so that yellow letters can't pair with them

            letter = Fore.GREEN + guessed_word[i] + Fore.RESET
            letter_index_pairs.append({i: letter})
    
    # This loop will get all the yellow and gray letters from the word next
    for i in range(0, 5):
        if selected_word[i] != "-": # not allowing dashes
            if guessed_word[i] != selected_word[i] and guessed_word[i] in selected_word: # yellow letter checking
                letter = Fore.YELLOW + guessed_word[i] + Fore.RESET
                letter_index_pairs.append({i: letter})

            else: # otherwise considering the letter as grey
                letter = Fore.LIGHTBLACK_EX + guessed_word[i] + Fore.RESET
                letter_index_pairs.append({i: letter})

    letter_index_pairs = sorted(letter_index_pairs, key=lambda d: list(d.keys())[0]) # Sorting the pairs by their index in the word
    
    # getting the finalized guessed words colors
    guessed_word_colors = []
    for pair in letter_index_pairs:
        guessed_word_colors.extend(list(pair.values()))

    return guessed_word_colors


def get_game_table():
    """This function will get a table for the game"""

    table = PrettyTable()
    table.header = False

    return table


def add_guessed_word_to_table(table, guessed_word_colors):
    """This function will add the colored guessed word onto the game table"""
    table.add_row(guessed_word_colors)
    print(table)


def is_correct_word(guessed_word, selected_word):
    """This function will return a boolean value if the guessed word is correct"""

    if selected_word == guessed_word:
        return True

    return False


def game():
    print("Welcome to Wordle Unlimited!")

    selected_word = "NANNY"
    table = get_game_table()

    chance_number = 0

    while chance_number != 6:
        guessed_word = ask_guessed_word()

        guessed_word_colors = get_guessed_word_colors(guessed_word, selected_word)
        add_guessed_word_to_table(table, guessed_word_colors)

        if is_correct_word(guessed_word, selected_word):
            print(f"Correct! The word was: {selected_word}")
            print(f"You got it on chance #{chance_number}!")

            quit()

        else:
            chance_number += 1

    print(f"You ran out of chances! The word was: {selected_word}")


game()

I'm programming a custom Python Wordle game. It was working great, until I came across this issue.

For example, when the correct word to guess is "NANNY" and the user guesses "DEALT" it works perfectly; D, E, L, and T are considered grey letters and A is considered a yellow letter:

(https://i.sstatic.net/DbPLb.png)

However, when the user guesses a word like "NORTH" I get the following error:

  File "C:\Users\hasee\OneDrive\Documents\wordle unlimited\main.py", line 123, in <module>
    game()
  File "C:\Users\hasee\OneDrive\Documents\wordle unlimited\main.py", line 109, in game
    add_guessed_word_to_table(table, guessed_word_colors)
  File "C:\Users\hasee\OneDrive\Documents\wordle unlimited\main.py", line 84, in add_guessed_word_to_table
    table.add_row(guessed_word_colors)
  File "C:\Users\hasee\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\prettytable\prettytable.py", line 1407, in add_row
    raise ValueError(
ValueError: Row has incorrect number of values, (actual) 3!=5 (expected)

I expected it to show 'N' as green, and the rest grey. I went through guessed_word_colors() and couldn't work out why this error is happening.


Solution

  • Here's a cleaned up version of your code that works. Note that I have removed the prettytable stuff, but it should be easy for you to add this in:

    def ask_guessed_word():
        return input("Type in your word: ").upper()
    
    def get_guessed_word_colors(guessed_word, selected_word):
        letter_index_pairs = ['']*len(selected_word)
        selected_word = list(selected_word)
        
        # Getting all the green letters from the word first
        
        for i in range(len(selected_word)):
            if guessed_word[i] == selected_word[i]:
                selected_word[i] = "-" # replacing the green letters to dashes so that yellow letters can't pair with them
                letter_index_pairs[i] = "[[" + guessed_word[i] + "]]"
        
        # This loop will get all the yellow and gray letters from the word next
        for i in range(len(selected_word)):
            if guessed_word[i] in selected_word: # yellow letter checking
                letter_index_pairs[i] = " [" + guessed_word[i] + "] "
            elif selected_word[i] != '-':
                letter_index_pairs[i] = "  " + guessed_word[i] + "  "
    
        return letter_index_pairs
    
    
    def get_game_table():
        return []
    
    
    def add_guessed_word_to_table(table, guessed_word_colors):
        """This function will add the colored guessed word onto the game table"""
        table.append(guessed_word_colors)
        for row in table:
            print(row)
    
    
    def is_correct_word(guessed_word, selected_word):
        return selected_word == guessed_word
    
    
    def game():
        print("Welcome to Wordle Unlimited!")
    
        selected_word = "NANNY"
        table = get_game_table()
    
        for chance_number in range(6):
            guessed_word = ask_guessed_word()
    
            guessed_word_colors = get_guessed_word_colors(guessed_word, selected_word)
            add_guessed_word_to_table(table, guessed_word_colors)
    
            if is_correct_word(guessed_word, selected_word):
                print(f"Correct! The word was: {selected_word}")
                print(f"You got it on chance #{chance_number+1}!")
                return
    
        print(f"You ran out of chances! The word was: {selected_word}")
    
    game()