36 Commits

Author SHA1 Message Date
Brunus
7f54aece7b Upload New File 2026-02-26 08:54:42 +00:00
Brunus
c6fb7ebbae Delete fr_10letters.json 2026-02-26 08:54:01 +00:00
Brunus
0e6ce6e249 Edit README.md 2026-02-26 08:53:44 +00:00
Brunus
465bfb78f7 Edit README.md 2026-02-26 08:43:28 +00:00
Brunus
1644254162 Nouveau dictionnaire de mots en 10 lettres 2026-02-26 08:39:53 +00:00
Brunus
48dbc04d0c correction de mots avec espace en dernière lettre 2022-01-26 11:22:23 +01:00
Brunus
d92925ed07 Update README.md 2022-01-26 08:41:06 +00:00
Brunus
78af8000e8 Update README.md 2022-01-26 08:37:28 +00:00
01a6b4ca6b bugfix : ne pas utiliser pattern et firsttry ensemble 2022-01-25 15:46:05 +01:00
443d5facd5 Création d'un nouveau dictionnaire fr à base d'autres dictionnaires 2022-01-25 15:46:05 +01:00
79540341d4 Réécriture du dictionnaire Sutom (gain de place) 2022-01-25 15:46:04 +01:00
53e6d2f2ac Mise à jour de l'aide pour la fonction pattern 2022-01-25 15:46:04 +01:00
07bc289c03 Amélioration de "resolv_pattern()" 2022-01-25 15:46:04 +01:00
09f1f8f65d Travaille en majuscule 2022-01-25 15:46:04 +01:00
86d2fcee4e "not in" 2022-01-25 15:46:04 +01:00
91de6012dc Optimisation de "resolv_bl()" 2022-01-25 15:46:04 +01:00
41b7681e04 Optimisation de "noDouble()" 2022-01-25 15:46:04 +01:00
8bf0ec59df Optimisations 2022-01-25 15:46:04 +01:00
7a163e8f4b Nettoyage 2022-01-25 10:42:54 +01:00
afbf6e87c5 Fonction "Pattern" 2022-01-25 10:42:54 +01:00
d5c4b4b233 Fonction "Bad Letters" 2022-01-25 10:42:54 +01:00
4513f059f0 Fonction "Know Letters" 2022-01-25 10:42:54 +01:00
d3f994ea92 Nettoyage 2022-01-25 10:42:54 +01:00
1eca719fd8 Fonction "First Try" 2022-01-25 10:42:54 +01:00
ecff9a87bd Réorganisation du code 2022-01-25 10:42:54 +01:00
ba37f6c03e Ajout de l'option "no double" 2022-01-25 10:42:54 +01:00
98d4966a5b Préparation pour l'affichage des résultats 2022-01-25 10:42:54 +01:00
f879e01397 Simplification de l'argument du nombre de lettre 2022-01-25 10:42:54 +01:00
b19ad51639 Fonction pour charger le dictionnaire et début de mise en forme du programme 2022-01-25 10:42:54 +01:00
6183c8a4f5 Fonction pour la longueur du mot 2022-01-25 10:42:54 +01:00
9144e942c9 Fonction pour la première lettre 2022-01-25 10:42:54 +01:00
d80816a0b1 Simplification du argparse 2022-01-25 10:42:54 +01:00
826df9c336 Comme l'on a des arguments obligatoires, pas de besoin de vérifier s'il y en a. 2022-01-25 10:42:54 +01:00
cd3da5357a Ouvre le dictionnaire avec un 'with statement' 2022-01-25 10:42:54 +01:00
d62ace44a4 import os : pas besoin 2022-01-25 10:42:54 +01:00
ecc47f1008 Python3 2022-01-25 10:42:54 +01:00
6 changed files with 5270 additions and 149675 deletions

View File

@@ -1,16 +1,19 @@
# wgamesolv # wgamesolv
Words Games Solver. WARNING : le dictionnaire fr_FR.json n'est plus à jour. Il doit soit être mis à jour soit remplacé par des dictionnaires de mots en x lettres, comme le nouveau fr_A_10letters.json (mots de 10 lettres commençants par la letre A) qui lui est à jour (le 26 fév. 2026).
Script d'aide à la résolution des jeux de mots style wordle
Utilisation : wgamesolv.py -fl L -nb 7 (autres options) 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, Brunus.
Courageux testeur des 1ères versions et précieux apporteur d'idées: DarKou.
Licence : MIT
Utilisation : wgamesolv.py -d dictionnaire.json -nb 7 (autres options)
-d, --dictionary : dictionnaire à utiliser -d, --dictionary : dictionnaire à utiliser
ex : -d SutomList.json ex : -d fr_Fc.json
Les dictionnaires sont récupérables ici : Trois dictionnaires ont été fusionnés pour n'en faire qu'un : Wordle, SUTOM et l'officiel du Scrabble
https://framagit.org/JonathanMM/sutom/-/blob/main/ts/mots/listeMotsProposables.ts
Et :
https://raw.githubusercontent.com/LouanBen/wordle-fr/main/mots.txt
-fl, --firstLetter : première lettre du mot -fl, --firstLetter : première lettre du mot
ex : -fl C ex : -fl C
@@ -22,7 +25,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. -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 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 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. -nd, --noDoubleLetters : filtre les mots composé d'une seule occurence de chaque lettre.
@@ -32,7 +35,8 @@ ex : -kl AEP
-bl, --badLetters : lettres déjà invalidées -bl, --badLetters : lettres déjà invalidées
ex : -bl ZTOR ex : -bl ZTOR
-p, --pattern : lettres validées et bien placées, séparée par des '.' pour les lettres non validées -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
ex : -p L..I... (le mots était LUCIOLE) 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

5071
fr_A_10letters.json Normal file

File diff suppressed because it is too large Load Diff

1
fr_FR.json Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,242 +1,204 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import sys
import json import json
import argparse import argparse
from random import shuffle
parser = argparse.ArgumentParser(
description='Cheating with SUTOM'
)
parser.add_argument(
'-d',
'--dictionary',
help='Dictionnaire des mots du jeu',
required=True
)
parser.add_argument(
'-fl',
'--firstLetter',
help='Première lettre',
required=True
)
parser.add_argument(
'-nb',
'--nbLetters',
type=int,
help='Nombre de lettres, un entier',
required=True
)
parser.add_argument(
'-kl',
'--knownLetters',
help='Lettres connues, hors première, sans espaces : -kl BE'
)
parser.add_argument(
'-bl',
'--badLetters',
help='Lettres non valides, sans espaces : -bl AKL'
)
parser.add_argument(
'-p',
'--pattern',
help='Placement, avec des "." pour les inconnues : -p A...T.I.'
)
parser.add_argument(
'-nd',
'--noDoubleLetters',
help="Option pour ne chercher que des mots ne contenant qu'une occurence de chaque lettre",
action="store_true"
)
parser.add_argument(
'-ft',
'--firstTry',
type=int,
help="Sélectionne des mots commençants par firstLetter et composés de ft voyelles différentes: -ft 4",
)
if not len(sys.argv) > 1: def load_dict(dict_file):
print("-h or --help pour afficher l'aide") try:
exit(1) with open(dict_file, "r") as dico:
liste = json.load(dico)
args = parser.parse_args() return liste
except Exception as error:
# Dictionary print(f"Impossible d'ouvrir le fichier {dict_file} : {error}")
if args.dictionary:
fp = args.dictionary
try :
f = open(fp)
liste = json.load(f)
except:
print("Impossible d'ouvrir le fichier" + fp)
# First Letter
if args.firstLetter:
fl = args.firstLetter
else:
fl = False
# Nbr Letters
if args.firstLetter:
nb = args.nbLetters
else:
nbLetters = False
# Pattern
if args.pattern:
pattern = args.pattern
if args.nbLetters and len(pattern) != nb:
print("Tu as merdé ta pattern petit scarabé !")
exit(2) exit(2)
else:
pattern = False
# Known Letters
if args.knownLetters:
kl = args.knownLetters
else:
kl = False
# Bad Letters
if args.badLetters:
bl = args.badLetters
else:
bl = False
# No Double
if args.noDoubleLetters:
nd = True
else: nd = False
# First Try
if args.firstTry:
ft = args.firstTry
else: ft = False
patternFilter = []
klFilter = []
blFilter = []
ftFilter = []
# Fonction d'élimination de mots contenant plusieurs occurences de lettres
def noDouble(mots): def noDouble(mots):
# Fonction d'élimination de mots contenant plusieurs occurences de lettres
ndList = [] ndList = []
for mot in mots: for mot in mots:
llist = [] if len(list(mot)) == len(set(list(mot))):
for l in mot:
if not l in llist:
llist.append(l)
if len(mot) == len(llist):
ndList.append(mot) ndList.append(mot)
return(ndList) return ndList
# First Try : sélectionne des mots ayant des chances de valider ou invalider des voyelles
def firstTryFilter(mots, ft):
vLetters = ['A', 'E', 'I', 'O', 'U', 'Y']
bestWords = []
for mot in mots:
vCount = 0
for l in mot:
if l in vLetters:
vCount +=1
if vCount >= ft:
bestWords.append(mot)
return(bestWords)
# Fonction de comparaison des lettres d'un mot, avec celle de la pattern def firstTryFilter(mots, max_mots, pattern):
# Plus nécessaire actuellement mais peut être dans une prochaine vie '''
''' First Try : sélectionne des mots ayant des chances de valider ou invalider
def patternCheck(pattern, mot, l): l'une des lettres les plus utilisée en français.
goodPosCounter = 0 '''
for pos in range(len(pattern)): if pattern:
print("Checking : " + l + "against : " + pattern[pos] + " and " + mot[pos]) return mots # Inhibe le filtre si on utilise aussi un pattern
if pattern[pos] == l and mot[pos] == l:
goodPosCounter +=1
print("checked")
if goodPosCounter == pattern.count(l):
return(0)
else: else:
return(1) 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
# First Letter : élimination des mots ne commençant pas par FirstLetter
if fl:
goodFl = [mot for mot in liste if mot.startswith(fl)]
# Nb Lettres : élimination des mots n'ayant pas le bon nombre de lettres def resolv_fl(liste, firstletter):
if fl: # On ne garde que les mots qui commence par FirstLetter
goodLen = [mot for mot in goodFl if len(mot) == nb] firstletter = firstletter.upper()
else: return [mot for mot in liste if mot[0] == firstletter]
goodLen = [mot for mot in liste if len(mot) == nb]
# First Try
if ft:
bestWords = noDouble(firstTryFilter(goodLen, ft))
# Pattern : élimination des mots ne satisfaisant pas la pattern def resolv_len(liste, lenght):
if pattern: # On ne garde que les mots qui ont la bonne longueur
patternCount = len(pattern) - pattern.count(".") return [mot for mot in liste if len(mot) == lenght]
for mot in goodLen:
patternEval = 0
for l in range(len(mot)):
if mot[l] == pattern[l]:
patternEval += 1
if patternEval == patternCount :
patternFilter.append(mot)
# Known Letters : élimination des mots ne comprenant pas les lettres validées (hors pattern)
if kl: def resolv_pattern(liste, pattern):
if patternFilter: # Pattern : élimination des mots ne satisfaisant pas la pattern
mots = patternFilter pattern_dict, not_pattern_dict = {}, {}
for lettre in pattern:
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:
if mot[key] == pattern_dict[key]:
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
def resolv_kl(liste, lettres):
'''
Known Letters : élimination des mots ne comprenant pas
les lettres validées (hors pattern)
'''
lettres = list(set(list(lettres.upper())))
MotsRestants = []
for mot in liste:
if len(set(lettres).intersection(mot)) == len(lettres):
MotsRestants.append(mot)
return MotsRestants
def resolv_bl(liste, lettres):
'''
Bad Letters : élimination des mots contenant
des lettres invalidées (hors pattern)
'''
lettres = list(set(list(lettres.upper())))
MotsSuppr = []
for mot in liste:
for lettre in lettres:
if lettre in mot:
MotsSuppr.append(mot)
return [mot for mot in liste if mot not in MotsSuppr]
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Cheating with SUTOM'
)
parser.add_argument(
'-d',
'--dictionary',
help='Dictionnaire des mots du jeu',
required=True
)
parser.add_argument(
'-fl',
'--firstLetter',
help='Première lettre',
default=False
)
parser.add_argument(
'-nb',
'--nbLetters',
type=int,
help='Nombre de lettres, un entier',
default=False,
required=True
)
parser.add_argument(
'-kl',
'--knownLetters',
default=False,
help='Lettres connues, hors première, sans espaces : -kl BE'
)
parser.add_argument(
'-bl',
'--badLetters',
default=False,
help='Lettres non valides, sans espaces : -bl AKL'
)
parser.add_argument(
'-p',
'--pattern',
default=False,
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',
'--noDoubleLetters',
help="Option pour ne chercher que des mots ne contenant qu'une occurence de chaque lettre",
default=False,
action="store_true"
)
parser.add_argument(
'-ft',
'--firstTry',
default=False,
type=int,
help="Sélectionne des mots commençants par firstLetter et composés de ft voyelles différentes: -ft 4",
)
args = parser.parse_args()
if args.pattern and args.nbLetters and len(args.pattern) != args.nbLetters:
print("Tu as merdé ta pattern petit scarabé !")
exit(2)
liste = load_dict(args.dictionary)
liste = resolv_len(liste, args.nbLetters)
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, args.pattern)
if len(liste) == 1:
print(f"Essaie : \"{liste[0]}\"")
elif len(liste) > 1:
print(f"Mots à tester : {liste}")
else:
print("Hmmm... Je crois qu'on s'est perdu...")
exit(0)
if len(liste) > 1:
print(liste)
print(f"Il y a {len(liste)} mots dans la liste")
elif len(liste) == 1:
print(f"La solution est \"{liste[0]}\".")
else: else:
mots = goodLen print("Hmmm... Je crois qu'on s'est perdu...")
for mot in mots:
validate = 0
for l in kl:
if l in mot:
validate += 1
if validate == len(kl):
klFilter.append(mot)
# Bad Letters : élimination des mots contenant des lettres invalidées (hors pattern)
if bl:
if klFilter:
mots = klFilter
elif patternFilter:
mots = patternFilter
else:
mots = goodLen
for mot in mots:
invalidate = 0
for l in bl:
if l in mot and l in pattern:
if pattern.count(l) != mot.count(l):
invalidate += 1
elif l in mot:
invalidate += 1
if invalidate == 0:
blFilter.append(mot)
# Affiche du résultat
if pattern and kl and bl:
print(", ".join(blFilter))
print(str(len(blFilter)) + " mots dans la liste" )
elif pattern and kl:
print(", ".join(klFilter))
print(str(len(klFilter)) + " mots dans la liste" )
elif pattern:
print(", ".join(patternFilter))
print(str(len(patternFilter)) + " mots dans la liste" )
elif kl and bl:
print(", ".join(blFilter))
print(str(len(blFilter)) + " mots dans la liste" )
elif bl and pattern:
print(", ".join(blFilter))
print(str(len(blFilter)) + " mots dans la liste" )
elif ft:
print(", ".join(bestWords))
print(str(len(bestWords)) + " mots dans la liste" )
else:
print(", ".join(goodLen))
print(str(len(goodLen)) + " mots dans la liste" )