#!/usr/bin/python import random from enum import Enum import dictionary class LetterResult(Enum): """Is an individual letter in a word in the result?""" CORRECT = "C" MOVE = "M" INCORRECT = "I" UNKNOWN = "U" class InvalidWord(Exception): """Thrown when an input word is not a valid Wordle.""" pass def select_word(words=dictionary.words()): return random.choice(list(words)) def grade_word(target, guess, words=dictionary.words()): # We don't check word length, since all valid words are 5 letters. if guess not in words: raise InvalidWord(f"{guess} is not a valid Wordle.") result = [LetterResult.UNKNOWN] * dictionary.WORDLE_LENGTH # We copy target, and remove letters if we find them. This handles duplicate letters correctly. # For example, if the target is "pulls" and we guess "apple", only the first "p" should be a # MOVE. The second should be INCORRECT. remaining = list(target) # Find all correct results first. for i in range(dictionary.WORDLE_LENGTH): if target[i] == guess[i]: result[i] = LetterResult.CORRECT remaining.remove(guess[i]) for i in range(dictionary.WORDLE_LENGTH): if result[i] == LetterResult.UNKNOWN: if guess[i] in remaining: # Letter is in the wrong place. result[i] = LetterResult.MOVE remaining.remove(guess[i]) else: # Letter is not in target. result[i] = LetterResult.INCORRECT return result def display_result(result, text): opening = { LetterResult.CORRECT: "\033[92m", LetterResult.MOVE: "\033[33m", LetterResult.INCORRECT: "\033[36m", LetterResult.UNKNOWN: "", } closing = "\033[0m" return f"{opening[result]}{text}{closing}" def success_result(result): for r in result: if r != LetterResult.CORRECT: return False return True