Jouez à Wordle sur ESP32 (du neuf !)

Wordle est le petit jeu à la mode en ce moment, en Anglais cependant, mais on peut certainement trouver des clones en Français.

Pour y jouer en ligne, c'est ici :
https://www.powerlanguage.co.uk/wordle/

Le principe est simple, il ressemble au MasterMind de notre enfance mais avec des mots. Vous avez 6 propositions pour trouver un mot. Chaque lettre bien placée, mal placée ou absente est indiquée en retour.

J'en ai fait une version sur ESP32, en Anglais et en Français. Deux programmes, l'un est purement verbeux, l'autre est graphique et tourne sur TT-GO T-Display.

Tout est là :

Amusez-vous bien...

super !

NEW : Comment gagner à Wordle ?
J'ai fait un script Python qui permet de gagner à Wordle. Il n'est pas garanti qu'il suggère le bon mot en 6 coups au plus, mais tous mes tests trouvent en 4 ou 5 essais

Bon, c'est du Python, donc ça n'a pas sa place dans ce forum, mais c'est fun...

# -*- coding: utf-8 -*-
"""
Created on Fri Jan 28 09:22:15 2022

@author: Lesept

Howto:
    First go to the Wordle website: https://www.powerlanguage.co.uk/wordle/
    Enter your first guess: I use 'above' but there are other suggestions
    (https://www.polygon.com/gaming/22884031/wordle-game-tips-best-first-guess-5-letter-words)
    Wordle answers with colored letters: enter this answer using the following code
        use - for grey (letter not in the word)
        use = for yellow (letter misplaced)
        use + for green (correct place)
    For example : -+==-
    I suggest a word : play it in Wordle
    Enter Wordle's answer until you find the correct word
"""

def intersection(lst1, lst2):
    return list(set(lst1) & set(lst2))

# Compute the score of a word
def score(word, Wordle):
    score = "-----"

    for i in range(len(word)):
        if Wordle[i] == word[i]:
            Wordle = Wordle[:i]+'0'+Wordle[i+1:]
            score  = score[:i]+'+'+score[i+1:]

    for j in range(len(word)):
        if score[j]=='+': continue
        comp = [i for i in range(len(Wordle)) if Wordle.startswith(word[j], i)]
        if comp == []:
            score  = score[:j]+'-'+score[j+1:]
        else:
            score  = score[:j]+'='+score[j+1:]
    return score

# Search words matching a given score
def search(filename, target, guess, wordList):
    Nwords = len(wordList)
    count = 0
    lst = []
    for i in range(Nwords):
        test = wordList[i]
        if score(guess, test) == target:
            count += 1
            lst.append(test)
    return count, lst
# 
# Main code
# 

if __name__ == '__main__':
    filename = "Dict-5757.txt"          # uncomment for english game
    # filename = "Dict-FR-7980.txt"     # uncomment for french game
    found = False
    lst = []

# Create the initial list of words    
    wordList = []
    with open(filename) as file:
        Lines = file.readlines()
        for line in Lines:
            line = line[:-1].lower().split()
            for i in range(len(line)):
                wordList.append(line[i])
        
    word = input ("Enter your initial guess: ")
# Main loop : search for words fitting the scores, and reduce the search scope
    while not found:
        s = input ("Enter your score (or 0 if the word was unknown): ")
        if s == '0':
            print('A few more suggestions: choose one...')
            for i in range(min(5,len(lst))):
                print(lst[i], end = ' ')
            word = input ("Enter your new guess: ")
            continue
        elif s == '+++++':
            print('Congratulations !!!')
            found = True
        elif s == '-----':
            print("That wasn't a good guess. Try playing a word with several vowels such as: adieu, about, above...")
        else:
            count, lst = search(filename, s, word, wordList)
            if count == 0:
                import sys
                sys.exit('no matching word: please try again from the beginning')
            else:
                print(f'Found {count} matching words --> my suggestion: {lst[0]}')
                wordList = intersection(lst, wordList)
                word = lst[0]

Aujourd'hui : trouvé en 4 coups...

Les instructions sont en haut dans le code. In french :

Allez d'abord sur le site Wordle : https://www.powerlanguage.co.uk/wordle/
Entrez votre première réponse : j'ai utilisé 'above' mais il y a d'autres suggestions.
(https://www.polygon.com/gaming/22884031/wordle-game-tips-best-first-guess-5-letter-words)
Wordle répond avec des lettres colorées : entrez cette réponse en utilisant le code suivant
    utilisez - pour le gris (lettre absente du mot)
    utiliser = pour le jaune (lettre mal placée)
    utiliser + pour le vert (place correcte)
Par exemple : ----= (la réponse pour above) ou -=+=- (la réponse pour lyres)
Je propose un mot : jouez-le dans Wordle
Entrez la réponse de Wordle jusqu'à ce que vous trouviez le bon mot.

Pour y jouer en français, c'est ici

Il suffit de changer le nom du fichier de dictionnaire ici :
filename = "Dict-5757.txt"
Les dictionnaires sont dans le lien Instructables plus haut, avec un dico en français. D'ailleurs, ça a été un peu plus dur :

J'hésite à proposer ça sur Instructables... Ca risque de dynamiter le jeu... qu'en pensez-vous ?

En attendant, c'est sur GitHub :

Une amélioration du code (et une correction) qui permet de trouver le Wordle d'aujourd'hui en 3 coups au lieu de 4

# -*- coding: utf-8 -*-
"""
Created on Fri Jan 28 09:22:15 2022

@author: Lesept

Dependency : textdistance (pip install textdistance)

Howto:
    First go to the Wordle website: https://www.powerlanguage.co.uk/wordle/
    Enter your first guess: I use 'above' but there are other suggestions
    (https://www.polygon.com/gaming/22884031/wordle-game-tips-best-first-guess-5-letter-words)
    Wordle answers with colored letters: enter this answer using the following code
        use - for grey (letter not in the word)
        use = for yellow (letter misplaced)
        use + for green (correct place)
    For example : -+==-
    I suggest a word : play it in Wordle
    Enter Wordle's answer until you find the correct word
"""

import textdistance

def intersection(lst1, lst2):
    return list(set(lst1) & set(lst2))

def diversity(word):
    return len(set(word)) / 5

# Compute the score of a word
def score(word, Wordle):
    score = "-----"
    nomore = []

    for i in range(len(word)):
        if Wordle[i] == word[i]:
            Wordle = Wordle[:i]+'0'+Wordle[i+1:]
            score  = score[:i]+'+'+score[i+1:]

    for j in range(len(word)):
        if score[j]=='+': continue
        comp = [i for i in range(len(Wordle)) if Wordle.startswith(word[j], i)]
        if comp == []:
            res = '-'
        else:
            comp2 = []
            for i in range(len(comp)):
                if comp[i] not in nomore:
                    comp2.append(comp[i])
            if comp2 != []:
                res = '='
                nomore.append(comp2[0])
                score  = score[:j] + res + score[j+1:]
    return score

# Search words matching a given score
def search(filename, target, guess, wordList):
    Nwords = len(wordList)
    count = 0
    lst = []
    for i in range(Nwords):
        test = wordList[i]
        if score(guess, test) == target:
            count += 1
            lst.append(test)
    return count, lst

# Select in the list the farthest word from last guess
def select(guess, lst):
    if len(lst) == 1:
        return lst[0]
    maxdist = 0
    number = 0
    bestword = ''
    for word in lst:
        # dist = textdistance.bwtrle_ncd.distance(guess, word)
        dist = textdistance.entropy_ncd.distance(guess, word)
        # dist = textdistance.mra.distance(guess, word)
        # dist = textdistance.editex.distance(guess, word)
        dist *= diversity(word)
        if dist > maxdist:
            maxdist = dist
            bestword = word
            number = 0
        if dist == maxdist:
            number += 1
    return bestword

# 
# Main code
# 

if __name__ == '__main__':
    filename = "Dict-5757.txt"          # uncomment for english game
    # filename = "Dict-FR-7980.txt"     # uncomment for french game
    found = False
    lst = []

# Create the initial list of words    
    wordList = []
    with open(filename) as file:
        Lines = file.readlines()
        for line in Lines:
            line = line[:-1].lower().split()
            for i in range(len(line)):
                wordList.append(line[i])
        
    word = input ("Enter your initial guess: ")
# Main loop : search for words fitting the scores, and reduce the search scope
    while not found:
        s = input ("Enter your score (or 0 if the word was unknown): ")
        if s == '0':
            print('A few more suggestions: choose one...')
            for i in range(min(5,len(lst))):
                print(lst[i], end = ' ')
            word = input ("Enter your new guess: ")
            continue
        elif s == '+++++':
            print('Congratulations !!!')
            found = True
        elif s == '-----':
            print("That wasn't a good guess. Try playing a word with several vowels such as: adieu, about, above...")
        else:
            count, lst = search(filename, s, word, wordList)
            if count == 0:
                import sys
                sys.exit('no matching word: please try again from the beginning')
            else:
                suggest = select(word, lst)
                print(f'Found {count} matching words --> my suggestion: {suggest}')
                wordList = intersection(lst, wordList)
                word = suggest

A utiliser plutôt que la version précédente...