17 Commits

Author SHA1 Message Date
31ecc3306c correction de mots avec espace en dernière lettre 2022-01-26 11:37:09 +01:00
193ecb1f3a Update README.md 2022-01-26 10:04:32 +01:00
e040749bc1 bugfix : ne pas utiliser pattern et firsttry ensemble 2022-01-25 15:00:08 +01:00
0ee04abea4 Création d'un nouveau dictionnaire fr à base d'autres dictionnaires 2022-01-25 13:48:27 +01:00
9cfb21c160 Réécriture du dictionnaire Sutom (gain de place) 2022-01-25 13:43:54 +01:00
578bc69820 Mise à jour de l'aide pour la fonction pattern 2022-01-25 13:16:38 +01:00
9c9439b39b Amélioration de "resolv_pattern()" 2022-01-25 13:13:38 +01:00
23c8f27def Travaille en majuscule 2022-01-25 13:03:50 +01:00
e34317000c "not in" 2022-01-25 12:59:08 +01:00
332c571b71 Optimisation de "resolv_bl()" 2022-01-25 12:57:12 +01:00
25669da340 Optimisation de "noDouble()" 2022-01-25 11:41:57 +01:00
6603f4012e Optimisations 2022-01-24 23:14:17 +01:00
fc93178303 Nettoyage 2022-01-24 22:22:40 +01:00
e4b517168a Fonction "Pattern" 2022-01-24 22:15:17 +01:00
e2452c1434 Fonction "Bad Letters" 2022-01-24 21:46:06 +01:00
f9cf15d487 Fonction "Know Letters" 2022-01-24 21:05:06 +01:00
758d6bb0bb Nettoyage 2022-01-24 20:21:54 +01:00
5 changed files with 102 additions and 149552 deletions

View File

@ -1,16 +1,17 @@
# wgamesolv # wgamesolv
Words Games Solver. Words Games Solver.
Script d'aide à la résolution des jeux de mots style wordle 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 -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 +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. -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 +33,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

1
fr_FR.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,15 +3,16 @@
import json import json
import argparse import argparse
from random import shuffle
def load_dict(dict_file): def load_dict(dict_file):
try : try:
with open(dict_file, "r") as dico: with open(dict_file, "r") as dico:
liste = json.load(dico) liste = json.load(dico)
return liste return liste
except: except Exception as error:
print("Impossible d'ouvrir le fichier" + fp) print(f"Impossible d'ouvrir le fichier {dict_file} : {error}")
exit(2) exit(2)
@ -19,48 +20,38 @@ def noDouble(mots):
# Fonction d'élimination de mots contenant plusieurs occurences de lettres # 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
def firstTryFilter(mots, max_mots):
def firstTryFilter(mots, max_mots, pattern):
''' '''
First Try : sélectionne des mots ayant des chances de valider ou invalider 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'] if pattern:
bestWords = [] return mots # Inhibe le filtre si on utilise aussi un pattern
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)
# Fonction de comparaison des lettres d'un mot, avec celle de la pattern
# Plus nécessaire actuellement mais peut être dans une prochaine vie
'''
def patternCheck(pattern, mot, l):
goodPosCounter = 0
for pos in range(len(pattern)):
print("Checking : " + l + "against : " + pattern[pos] + " and " + mot[pos])
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
def resolv_fl(liste, firstletter): def resolv_fl(liste, firstletter):
# On ne garde que les mots qui commence par FirstLetter # On ne garde que les mots qui commence par FirstLetter
firstletter = firstletter.upper()
return [mot for mot in liste if mot[0] == firstletter] return [mot for mot in liste if mot[0] == firstletter]
@ -69,53 +60,55 @@ def resolv_len(liste, lenght):
return [mot for mot in liste if len(mot) == lenght] return [mot for mot in liste if len(mot) == lenght]
# First Try def resolv_pattern(liste, pattern):
#if ft: # Pattern : élimination des mots ne satisfaisant pas la pattern
# bestWords = noDouble(firstTryFilter(goodLen, ft)) 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
# Pattern : élimination des mots ne satisfaisant pas la pattern
#if pattern:
# patternCount = len(pattern) - pattern.count(".")
# 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:
# if patternFilter:
# mots = patternFilter
# else:
# mots = goodLen
# 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) def resolv_kl(liste, lettres):
#if bl: '''
# if klFilter: Known Letters : élimination des mots ne comprenant pas
# mots = klFilter les lettres validées (hors pattern)
# elif patternFilter: '''
# mots = patternFilter lettres = list(set(list(lettres.upper())))
# else: MotsRestants = []
# mots = goodLen for mot in liste:
# for mot in mots: if len(set(lettres).intersection(mot)) == len(lettres):
# invalidate = 0 MotsRestants.append(mot)
# for l in bl: return MotsRestants
# if l in mot and l in pattern:
# if pattern.count(l) != mot.count(l):
# invalidate += 1 def resolv_bl(liste, lettres):
# elif l in mot: '''
# invalidate += 1 Bad Letters : élimination des mots contenant
# if invalidate == 0: des lettres invalidées (hors pattern)
# blFilter.append(mot) '''
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__": if __name__ == "__main__":
@ -132,8 +125,7 @@ if __name__ == "__main__":
'-fl', '-fl',
'--firstLetter', '--firstLetter',
help='Première lettre', help='Première lettre',
default=False, default=False
required=True
) )
parser.add_argument( parser.add_argument(
'-nb', '-nb',
@ -159,7 +151,7 @@ if __name__ == "__main__":
'-p', '-p',
'--pattern', '--pattern',
default=False, 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( parser.add_argument(
'-nd', '-nd',
@ -178,26 +170,24 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
if args.pattern and args.nbLetters and len(pattern) != nb: if args.pattern and args.nbLetters and len(args.pattern) != args.nbLetters:
print("Tu as merdé ta pattern petit scarabé !") print("Tu as merdé ta pattern petit scarabé !")
exit(2) exit(2)
# Known Letters
kl = args.knownLetters
# Bad Letters
bl = args.badLetters
# First Try
ft = args.firstTry
liste = load_dict(args.dictionary) liste = load_dict(args.dictionary)
liste = resolv_len(liste, args.nbLetters) 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: if args.noDoubleLetters:
liste = noDouble(liste) liste = noDouble(liste)
if args.knownLetters:
liste = resolv_kl(liste, args.knownLetters)
if args.badLetters:
liste = resolv_bl(liste, args.badLetters)
if args.firstTry: if args.firstTry:
liste = firstTryFilter(liste, args.firstTry) liste = firstTryFilter(liste, args.firstTry, args.pattern)
if len(liste) == 1: if len(liste) == 1:
print(f"Essaie : \"{liste[0]}\"") print(f"Essaie : \"{liste[0]}\"")
elif len(liste) > 1: elif len(liste) > 1: