-
Notifications
You must be signed in to change notification settings - Fork 0
/
WordleSolver.py
151 lines (131 loc) · 6.9 KB
/
WordleSolver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# ░██████╗░██╗░░░██╗░█████╗░███╗░░██╗████████╗██╗░░░██╗███╗░░░███╗ ░██████╗████████╗░█████╗░░█████╗░██╗░░██╗
# ██╔═══██╗██║░░░██║██╔══██╗████╗░██║╚══██╔══╝██║░░░██║████╗░████║ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██║░██╔╝
# ██║██╗██║██║░░░██║███████║██╔██╗██║░░░██║░░░██║░░░██║██╔████╔██║ ╚█████╗░░░░██║░░░███████║██║░░╚═╝█████═╝░
# ╚██████╔╝██║░░░██║██╔══██║██║╚████║░░░██║░░░██║░░░██║██║╚██╔╝██║ ░╚═══██╗░░░██║░░░██╔══██║██║░░██╗██╔═██╗░
# ░╚═██╔═╝░╚██████╔╝██║░░██║██║░╚███║░░░██║░░░╚██████╔╝██║░╚═╝░██║ ██████╔╝░░░██║░░░██║░░██║╚█████╔╝██║░╚██╗
# ░░░╚═╝░░░░╚═════╝░╚═╝░░╚═╝╚═╝░░╚══╝░░░╚═╝░░░░╚═════╝░╚═╝░░░░░╚═╝ ╚═════╝░░░░╚═╝░░░╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝
import configparser
import sys
# Чтение файла конфигурации
config = configparser.ConfigParser()
config.read('config.ini')
# Извлечение настроек из файла конфигурации
dictpath = config.get('Worlde', 'DictionaryPath')
validchars = config.get('Worlde', 'ValidCharacters')
wordlength = config.getint('Worlde', 'WordLength')
wordstoremove = config.get('Worlde', 'WordsToRemove').split(',')
# Проверка аргументов командной строки
if len(sys.argv) > 1:
dictpath = sys.argv[1]
# Чтение и обработка словаря
allwords = open(dictpath, "r").read().split('\n')
validwords = set()
for w in allwords:
if ("'" in w): continue
if (len(w) != wordlength): continue
for i in range(wordlength + 1):
if (i < wordlength and w[i] not in validchars): break
elif (i == wordlength): validwords.add(w.lower())
# Удаление определенных слов
for word in wordstoremove:
validwords.discard(word)
# Преобразование в список
validwords = list(validwords)
def isThisSecretAvailable(testword,mask,secret):
'''
mask: G,Y,N -- green, yellow, none
Return True if secret can be secret word with this testword and mask
'''
for i in range(len(mask)):
if(mask[i]=='N' and testword[i] not in secret):continue
if(mask[i]=='G' and testword[i]==secret[i]):continue
if(mask[i]=='Y' and testword[i] in secret and testword[i]!=secret[i]):continue
return False
return True
def getMask(testword,secret):
'''
Returns mask of NYG symbols for typed testword and secretword
'''
mask=""
for i in range(len(testword)):
if(testword[i]==secret[i]):mask+="G"
elif(testword[i] in secret):mask+="Y"
else:mask+="N"
return mask
def getAvailableWordsByMask(testword,mask,wordlist):
'''
Return list of available words by typed testword and mask
'''
validsecrets=[]
for w in wordlist:
if(isThisSecretAvailable(testword,mask,w)):
validsecrets.append(w)
return validsecrets
# Get more difference start step
print("Analyze dictionary ("+str(len(validwords))+" words)...")
testwordmasks=dict() # Сделаем словарь: слово -> множество возможных масок
for i in validwords:
testwordmasks[i]=set()
for s in validwords:
testwordmasks[i].add(getMask(i,s))
masksvariances=[] # Сделаем лист с информацией о количестве разных масок
for i in validwords:
masksvariances.append(len(testwordmasks[i]))
maxmasksvariances=max(masksvariances)
maxvariancewords1=[]
for i in range(len(validwords)):
if(masksvariances[i]==maxmasksvariances):
print(validwords[i])
maxvariancewords1.append(validwords[i])
def getBestSteps(wordlist,allwords=None):
'''
Get best step for find word in wordlist by allwords dictionary
HardMode on if allwords=None or allwords=wordlist
'''
if(allwords is None):
allwords=wordlist
testwordmasks=dict()
for i in allwords:
testwordmasks[i]=set()
for s in wordlist:
testwordmasks[i].add(getMask(i,s))
masksvariances=[]
for i in allwords:
masksvariances.append(len(testwordmasks[i]))
maxmasksvariances=max(masksvariances)
print("Different masks:",maxmasksvariances)
maxvariancewords=[]
maxvariancewords2=[]
maxvariancewords3=[]
for i in range(len(allwords)):
if(masksvariances[i]==maxmasksvariances):
print(allwords[i])
maxvariancewords.append(allwords[i])
if(maxmasksvariances==1):break
elif(masksvariances[i]==maxmasksvariances-1):
# На случай, если в maxvariancewords будет всего одно слово и его не будет в словаре игры
maxvariancewords2.append(allwords[i])
elif(masksvariances[i]==maxmasksvariances-2):
maxvariancewords3.append(allwords[i])
# Среди лучших вариантов я бы поставил на первое место те, в которых буквы не повторяются
maxvariancewords.sort(key=lambda x:-len(set(x)))
maxvariancewords2.sort(key=lambda x:-len(set(x)))
maxvariancewords3.sort(key=lambda x:-len(set(x)))
return maxvariancewords+maxvariancewords2+maxvariancewords3
def mainloop():
print("Enter one of next words:",maxvariancewords1,"("+str(maxmasksvariances)+" different masks)")
newwordlist=getAvailableWordsByMask(input("What word did you type: ").lower(),input("What mask did you get: ").upper(),validwords)
print("Found",len(newwordlist),"available words")
beststeps=getBestSteps(newwordlist,validwords)
if(len(beststeps)>7):beststeps=beststeps[:7]
print("Please, type one of next words:",beststeps)
while(len(newwordlist)>1):
newwordlist=getAvailableWordsByMask(input("What word did you type: ").lower(),input("What mask did you get: ").upper(),newwordlist)
print("Found",len(newwordlist),"available words")
if(len(newwordlist)==1):break
beststeps=getBestSteps(newwordlist,validwords)
if(len(beststeps)>7):beststeps=beststeps[:7]
print("Please, type one of next words:",beststeps)
print("Your word is",newwordlist)
if(__name__=="__main__"):
mainloop()