pythonwordle-gametermcolor

improper output while printing coloured letter of a word in a wordle game in python


import random
import sys   
from termcolor import colored

def print_menu():
    print("welcome to wordle !")
    print("type a 5 letter word and hit enter\n")

def read_random_word():
    with open('E:\kartikey\python\programs\wordle\words.txt') as word_database:
        #splitline so every line in the text file gets stored as a diferent array
        #block and since here every line is basically a word so every word gets stored as an individual array.
        words=word_database.read().splitlines()
        return random.choice(words).lower()
print_menu()
play_again=""

while play_again !="quit":  
    word=read_random_word()
    for attempt in range(1,7):
        guess=input().lower()
        for i in range(min(len(guess),5)):
            if guess[i]==word[i]:
                #end="" is used so it doesnt go to a new line after printing the coloured letter
                print(colored(guess[i],'green'), end="")  
            elif guess[i] in word:
                print(colored(guess[i],'yellow'), end="")
            else:
                print(guess[i] , end="")  
        if guess==word:
                print((f"\nyou got the word in {attempt} try"))
                break
        elif attempt==6:
            print(f"sorry the wordle was {word}")
play_again=input("type quit to exit otherwise click enter")

the error im getting is:

welcome to wordle !
type a 5 letter word and hit enter

poise
?[32mp?[0m?[32mo?[0m?[32mi?[0m?[32ms?[0m?[32me?[0m
you got the word in 1 try

When I don't use the colored() function this error is not appearing but gives this issue when using it.


Solution

  • When i don't use the colored() function this error is not appearing but gives this issue when using it.

    The issue is that what you see are escape sequences used to set the color of a single letter in the terminal output.

    Apparently you use a console/terminal which doesn't support escape sequences or run your code in some other environment which output does not support coloring.

    Your code runs perfectly and colors the hit letters in the output. Well done! Just run it in a console supporting escape sequences and enjoy!

    Happy coding :)

    CodeIsRunningOK

    Below a version of your code with following changes:


    # wordle.py 
    # https://stackoverflow.com/questions/73555383/improper-output-while-printing-coloured-letter-of-a-word-in-a-wordle-game-in-pyt
    # requires module 'termcolor' : 
    import random
    import sys   
    from termcolor import colored
    
    # --- wordle game parameter:
    WORD_LENGTH      = 5
    NO_OF_ATTEMPTS   = 7
    #                  ^-- to avoid constants spread within the code 
    # --- v-- input/output automation constants
    AUTOMATED_INPUT  = True  # False
    MAX_NO_OF_ROUNDS = 3 # set to negative value for an unlimited number
    WORDS_FROM_FILE  = False # True # False
    REVEAL_THE_WORD_TO_GUESS = True
    # ---
    # v-- automated input text
    mlnTextIO_mlnText = """\
    green
    blues
    mouse
    quit
    quit"""
    # v-- words to guess
    words = """\
    mouse
    mouse
    mouse""".splitlines()
    # --- 
    class mlnTextIO():
        def __init__(self, mlnText):
            self.lst_mlnText = mlnText.split('\n')
            self.lineNo = 0
            self.lenText=len(self.lst_mlnText)
        def input(self, promptText='without promptText'):
            # print('\n','input() called:', promptText)
            if promptText == 'without promptText':
                pass
            else:
               print(promptText)
            lineNo = self.lineNo
            self.lineNo += 1
            if promptText == "type quit to exit otherwise click enter":
                if lineNo < self.lenText: 
                    if self.lst_mlnText[lineNo] != "quit": 
                        self.lineNo -= 1
                        return '\n'
                    else: 
                        return 'quit'
                else: 
                    return 'quit'                
                #:if/else
            #:if
            if  lineNo < self.lenText:
                print(  self.lst_mlnText[lineNo])            
                return  self.lst_mlnText[lineNo]        
            else:
                return 'No further automated user input available.'
    #:def
    if AUTOMATED_INPUT: 
        input = mlnTextIO(mlnTextIO_mlnText).input
    
    def print_menu():
        print(f"  Welcome to wordle !")
        print(f"  Type a {WORD_LENGTH} letter word and hit enter\n")
    
    def get_random_word():
        global WORDS_FROM_FILE, words
        if WORDS_FROM_FILE: 
            with open('words.txt') as word_database:
                # splitline so every line in the text file gets stored as a diferent array
                # block and since here every line is basically a word so every word gets stored as an individual array.
                words=word_database.read().splitlines()
            WORDS_FROM_FILE = False
            # ^-- prevents file operation each time a word is requested
        return random.choice(words).lower()
    
    print_menu()
    play_again=""
    
    maxNoOfRounds = MAX_NO_OF_ROUNDS
    while play_again !="quit" and maxNoOfRounds > 0:
    
        if maxNoOfRounds == 0:
            print(colored(text="  Restart the program to play again", color='green', on_color='on_white', attrs=['bold']))
        maxNoOfRounds -= 1    
        
        word=get_random_word()
        if REVEAL_THE_WORD_TO_GUESS: 
            print(f'  Wordle word to guess is: "{word}"') # reveals the word to guess
    
        for attempt in range( 1, NO_OF_ATTEMPTS):
            guess=input().lower()
            for i in range( min(len(guess), WORD_LENGTH) ):
                if guess[i]==word[i]:
                    #end="" is used so it doesnt go to a new line after printing the coloured letter
                    print(colored(text=guess[i], color='white' , on_color='on_grey', attrs=['bold']),  end="")  
                elif guess[i] in word:
                    print(colored(text=guess[i], color='white' , on_color='on_grey'),                  end="")
                else:
                    print(colored(text=guess[i], color='red'   , on_color='on_grey', attrs=['bold']) , end="")  
            print()        
            if guess==word:
                print(f"  You got the word using {colored(text=str(attempt), color='white',on_color='on_grey', attrs=['bold'])} attempts")  
                break
            elif attempt==6:
                print(f"  Sorry, but the wordle was {colored(text=word, color='white',on_color='on_grey', attrs=['bold'])}")
            #if/elif
        #:for attempt
        play_again=input("  Type quit to exit otherwise click enter")
    #: while play_again
    

    The wordle when run in a console/terminal supporting escape sequences for colors and text layout looks now as follows:

    enter image description here

    The meaning of colors in the wordle output is as follows:

    And ... if you want to play it instead of playing around with its code just