Compare commits

...

14 Commits
v1.0 ... main

5 changed files with 60 additions and 149494 deletions

View File

@ -1,16 +1,17 @@
# wgamesolv
Words Games Solver.
Script d'aide à la résolution des jeux de mots style wordle
Words Games Solver.
Script d'aide à la résolution des jeux de mots style Wordle, SUTOM, mots-croisés, Scrabble...
On a fait ça pour s'amuser, pas spécialement pour tricher aux jeux de mots.
Auteurs : AntoineVe et Brunus.
Courageux testeur des 1ères versions et précieux apporteur d'idées: DarKou.
Licence : MIT
Utilisation : wgamesolv.py -fl L -nb 7 (autres options)
Utilisation : wgamesolv.py -d dictionnaire.json -nb 7 (autres options)
-d, --dictionary : dictionnaire à utiliser
ex : -d SutomList.json
Les dictionnaires sont récupérables ici :
https://framagit.org/JonathanMM/sutom/-/blob/main/ts/mots/listeMotsProposables.ts
Et :
https://raw.githubusercontent.com/LouanBen/wordle-fr/main/mots.txt
ex : -d fr_Fc.json
Trois dictionnaires ont été fusionnés pour n'en faire qu'un : Wordle, SUTOM et l'officiel du Scrabble
-fl, --firstLetter : première lettre du mot
ex : -fl C
@ -22,7 +23,7 @@ ex : -nb 7
-ft, --firstTry : optimise le premier essai en sortant les mots de -nb lettres, commençant par -fl lettre, ne contenant aucune lettre en plusieurs occurence et contenant -ft voyelles.
ex : -ft 4
Cette option peut être utilisée pour le tout premier essai, pour optimiser les chances d'avoir des lettres validées.
Cette option est ensuite inutile ou contre-productive pour les essais suivants.
Cette option est ensuite inutile ou contre-productive pour les essais suivants et ne peut pas être utilisée avec la pattern.
-nd, --noDoubleLetters : filtre les mots composé d'une seule occurence de chaque lettre.
@ -32,7 +33,8 @@ ex : -kl AEP
-bl, --badLetters : lettres déjà invalidées
ex : -bl ZTOR
-p, --pattern : lettres validées et bien placées, séparée par des '.' pour les lettres non validées
ex : -p L..I... (le mots était LUCIOLE)
-p, --pattern : lettres validées et bien placées, lettres connues et mal placées, séparée par des '.' pour les lettres non validées
Les lettres en caps sont les lettres connues et bien placées, les lettres en minuscules sont les lettres connues mais mal placées
ex : -p L.uI... (le mots était LUCIOLE)
Exemple complet : wgamesolv.py -d SutomList.json -nb 7 -fl L -p L..I... -kl E -bl AMNR
Exemple complet : wgamesolv.py -d fr_FR.json -nb 7 -fl L -p L.uI... -kl U -bl AMNR

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1
fr_FR.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@
import json
import argparse
from random import shuffle
def load_dict(dict_file):
@ -19,34 +20,38 @@ def noDouble(mots):
# Fonction d'élimination de mots contenant plusieurs occurences de lettres
ndList = []
for mot in mots:
llist = []
for lettre in mot:
if lettre not in llist:
llist.append(lettre)
if len(mot) == len(llist):
if len(list(mot)) == len(set(list(mot))):
ndList.append(mot)
return(ndList)
return ndList
def firstTryFilter(mots, max_mots):
def firstTryFilter(mots, max_mots, pattern):
'''
First Try : sélectionne des mots ayant des chances de valider ou invalider
l'une des lettres les plus utilisée en français
l'une des lettres les plus utilisée en français.
'''
bestLetters = ['E', 'A', 'I', 'R', 'S', 'N', 'T', 'O', 'L', 'U']
bestWords = []
for mot in mots:
for bestLetter in bestLetters:
if bestLetter in mot:
bestWords.append(mot)
bestWords = list(set(bestWords))
bestWords = noDouble(bestWords) # Autant maximiser les chances
bestWords = bestWords[0:max_mots]
return(bestWords)
if pattern:
return mots # Inhibe le filtre si on utilise aussi un pattern
else:
bestLetters = ['E', 'A', 'I', 'R', 'S', 'N', 'T', 'O', 'L', 'U']
bestWords = []
shuffle(mots)
mots = mots[:100]
for mot in mots:
for bestLetter in bestLetters:
if bestLetter in mot:
bestWords.append(mot)
bestWords = list(set(bestWords))
bestWords_noDouble = noDouble(bestWords) # Autant maximiser les chances
if len(bestWords_noDouble) > 0:
bestWords = bestWords_noDouble
bestWords = bestWords[:max_mots]
return bestWords
def resolv_fl(liste, firstletter):
# On ne garde que les mots qui commence par FirstLetter
firstletter = firstletter.upper()
return [mot for mot in liste if mot[0] == firstletter]
@ -57,10 +62,12 @@ def resolv_len(liste, lenght):
def resolv_pattern(liste, pattern):
# Pattern : élimination des mots ne satisfaisant pas la pattern
pattern_dict = {}
pattern_dict, not_pattern_dict = {}, {}
for lettre in pattern:
if lettre != ".":
if lettre != "." and lettre.isupper():
pattern_dict.update({pattern.index(lettre): lettre})
if lettre != "." and lettre.islower():
not_pattern_dict.update({pattern.index(lettre): lettre.upper()})
MotsOK, MotsKO = [], []
for mot in liste:
for key in pattern_dict:
@ -68,6 +75,10 @@ def resolv_pattern(liste, pattern):
MotsOK.append(mot)
else:
MotsKO.append(mot)
for key in not_pattern_dict:
if mot[key] == not_pattern_dict[key]:
MotsKO.append(mot)
MotsKO = set(MotsKO)
liste = [mot for mot in MotsOK if mot not in MotsKO]
liste = list(set(liste))
return liste
@ -78,7 +89,7 @@ def resolv_kl(liste, lettres):
Known Letters : élimination des mots ne comprenant pas
les lettres validées (hors pattern)
'''
lettres = list(set(list(lettres)))
lettres = list(set(list(lettres.upper())))
MotsRestants = []
for mot in liste:
if len(set(lettres).intersection(mot)) == len(lettres):
@ -91,18 +102,13 @@ def resolv_bl(liste, lettres):
Bad Letters : élimination des mots contenant
des lettres invalidées (hors pattern)
'''
lettres = list(set(list(lettres)))
lettres = list(set(list(lettres.upper())))
MotsSuppr = []
for mot in liste:
for lettre in lettres:
if lettre in mot:
MotsSuppr.append(mot)
for mot in MotsSuppr:
try:
liste.pop(liste.index(mot))
except ValueError:
pass
return liste
return [mot for mot in liste if mot not in MotsSuppr]
if __name__ == "__main__":
@ -119,8 +125,7 @@ if __name__ == "__main__":
'-fl',
'--firstLetter',
help='Première lettre',
default=False,
required=True
default=False
)
parser.add_argument(
'-nb',
@ -146,7 +151,7 @@ if __name__ == "__main__":
'-p',
'--pattern',
default=False,
help='Placement, avec des "." pour les inconnues : -p A...T.I.'
help='Placement : bien placée en majuscule, mal placée en minuscule et non existante par un \'.\'. E.g. : Ra..e.T'
)
parser.add_argument(
'-nd',
@ -171,11 +176,18 @@ if __name__ == "__main__":
liste = load_dict(args.dictionary)
liste = resolv_len(liste, args.nbLetters)
liste = resolv_fl(liste, args.firstLetter)
if args.firstLetter:
liste = resolv_fl(liste, args.firstLetter)
if args.pattern:
liste = resolv_pattern(liste, args.pattern)
if args.noDoubleLetters:
liste = noDouble(liste)
if args.knownLetters:
liste = resolv_kl(liste, args.knownLetters)
if args.badLetters:
liste = resolv_bl(liste, args.badLetters)
if args.firstTry:
liste = firstTryFilter(liste, args.firstTry)
liste = firstTryFilter(liste, args.firstTry, args.pattern)
if len(liste) == 1:
print(f"Essaie : \"{liste[0]}\"")
elif len(liste) > 1:
@ -183,12 +195,6 @@ if __name__ == "__main__":
else:
print("Hmmm... Je crois qu'on s'est perdu...")
exit(0)
if args.knownLetters:
liste = resolv_kl(liste, args.knownLetters)
if args.badLetters:
liste = resolv_bl(liste, args.badLetters)
if args.pattern:
liste = resolv_pattern(liste, args.pattern)
if len(liste) > 1:
print(liste)
print(f"Il y a {len(liste)} mots dans la liste")