1
- # https://github.com/dwyl/english-words for the list of words
1
+ # https://www.wordunscrambler.net/word-list/wordle-word-list for the list of words
2
2
3
3
from selenium import webdriver
4
4
from selenium .webdriver .common .by import By
8
8
import time
9
9
10
10
11
+ # This class is used to store data about the wordle such as :
12
+ # - the list of possible words
13
+ # - the letters that are present but not in the right position
14
+ # - the letters that are absent
15
+ # - the letters that are correct and their position in a list
16
+
11
17
class Finder :
12
18
def __init__ (self ):
13
19
self .possible_words = get_list_of_words ()
14
- self .absent_letters = set ([])
15
20
self .present_letters = set ([])
21
+ self .absent_letters = set ([])
16
22
self .word = ['' ] * 5
17
23
18
24
25
+ # Function that is called by the KeyboardListener
19
26
def on_release (key ):
20
27
# Start button
21
28
if key == keyboard .Key .esc :
22
29
return False # stop listener
23
30
24
31
32
+ # Get the status of the letters in the wordle
25
33
def get_row_results (game_row ):
26
34
tiles = game_row .find_elements (By .CLASS_NAME , "Tile-module_tile__3ayIZ" )
27
35
row_results = []
@@ -34,97 +42,73 @@ def get_row_results(game_row):
34
42
}
35
43
for tile in tiles :
36
44
row_results .append (res_to_int [tile .get_attribute ("data-state" )])
37
- print (row_results )
45
+ print (f"Row results : { row_results } " )
38
46
39
47
return tuple (row_results )
40
48
41
49
50
+ # Enter the word in the wordle
42
51
def enter_word (word ):
43
52
keyboard_controller = keyboard .Controller ()
44
53
keyboard_controller .type (word )
45
54
keyboard_controller .tap (keyboard .Key .enter )
46
55
time .sleep (2 )
47
56
48
57
49
- def create_regex (solving_string , present_letters ):
50
- regex = ""
51
- for letter in range (len (solving_string )):
52
- if solving_string [letter ] == "*" :
53
- regex += "[a-z]"
54
- elif solving_string [letter ] == "_" :
55
- regex += \
56
- "[^" + str (list (present_letters )).replace ("'" , "" ).replace ("," , "" ).replace ("[" , "" ).replace (" " , "" )
57
- else :
58
- regex += "[" + solving_string [letter ] + "]"
59
- return regex
60
-
61
-
62
- # Check word length
58
+ # Check word length, used in get_list_of_words() if the source list contains words with different length
63
59
def check_word_length (word ):
64
60
if len (word ) != 5 :
65
61
return False
66
62
else :
67
63
return True
68
64
69
65
66
+ # Check if a word contains a specific letter
70
67
def check_letter_in_word (letter , word ):
71
68
if letter in word :
72
69
return True
73
70
else :
74
71
return False
75
72
76
73
74
+ # Check if the letter in the finder object is the same as the letter in the possible answer
77
75
def check_match (finder_word_letter , possible_word_letter ):
78
76
if finder_word_letter == possible_word_letter :
79
77
return True
80
78
else :
81
79
return False
82
80
83
81
84
- # From the basic list of words, return all the words with 5 characters.
82
+ # From the wordle words list , return all the words
85
83
def get_list_of_words ():
86
- # list_of_words = open("words_alpha.txt", "r").read().strip().splitlines()
87
- list_of_words = open ("words_alpha_2.txt" , "r" ).read ().strip ().splitlines ()
88
- list_of_words = list (filter (check_word_length , list_of_words ))
84
+ list_of_words = open ("words_alpha.txt" , "r" ).read ().strip ().splitlines ()
89
85
90
- return list_of_words
86
+ # *** Use this if the source list contains words with different length ***
87
+ # list_of_words = list(filter(check_word_length, list_of_words))
91
88
92
- # Print to verify filtered_list only contains 5 characters words.
93
- # print("list of words : ", list_of_words)
89
+ return list_of_words
94
90
95
91
96
92
# Algorithm that solve the wordle
97
- # In the string we get :
98
- # _ : the letter is not on the right position (present)
99
- # * : the letter is not in the solution (absent)
100
- # X : the letter is on the right position (correct)
101
- # letters_not_in_response, is a list which keeps track of the allowed letters
102
- # letter_not_in_position, is a list which keeps track of the letters in bad position
103
- # For exemple, "A_A_*A", letters_not_in_response = ['B'], letter_not_in_position = ['K'].
104
93
def solving_algorithm (word , res , finder ):
105
- print ("solving_algorithm start" )
106
-
107
- solving_string = "*****"
94
+ print ("Starting solving algorithm" )
108
95
96
+ # Compare the word with the results of the wordle
109
97
for letter in range (len (word )):
110
- print ("letter : " , word [letter ])
111
98
if res [letter ] == 1 : # Case when the status of the letter is "correct"
112
- print ("the letter is correct" )
113
- solving_string = solving_string [:letter ] + word [letter ] + solving_string [letter + 1 :]
99
+ print (f"Letter { word [letter ]} is correct" )
114
100
finder .word [letter ] = word [letter ]
115
101
print (finder .word )
116
102
elif res [letter ] == 0 : # Case when the status of the letter is "present" (present but at the wrong position)
117
- print ("the letter is present" )
103
+ print (f"Letter { word [ letter ] } is present" )
118
104
finder .present_letters .add (word [letter ])
119
- solving_string = solving_string [:letter ] + "_" + solving_string [letter + 1 :]
120
105
else : # Case when the status of the letter is "absent"
121
- print ("the letter is absent" )
106
+ print (f"Letter { word [ letter ] } is absent" )
122
107
if word [letter ] not in finder .present_letters :
123
108
finder .absent_letters .add (word [letter ])
124
- solving_string = solving_string [:letter ] + "*" + solving_string [letter + 1 :]
125
109
126
- print ("Update list of words " )
127
- print ("length of list" , len ( finder . possible_words ) )
110
+ print ("\n " )
111
+ print ("Updating list of possible words ..." )
128
112
129
113
# Update list of words
130
114
for absent in finder .absent_letters :
@@ -138,28 +122,27 @@ def solving_algorithm(word, res, finder):
138
122
finder .possible_words = list (
139
123
filter (lambda x_word : check_match (x_word [i ], finder .word [i ]), finder .possible_words ))
140
124
125
+ print ("List of possible words updated !\n " )
126
+
141
127
print ("letter not in the right position : " , finder .present_letters )
142
128
print ("Letters with absent status" , finder .absent_letters )
143
129
print ("list of words : " , finder .possible_words )
144
130
print ("length of list" , len (finder .possible_words ))
145
131
146
- regex = create_regex (solving_string , finder .present_letters ) # Create the regex
147
- print (create_regex (solving_string , finder .present_letters ))
148
-
149
- # print("solving string :", solving_string)
150
-
151
132
152
133
def main ():
153
134
# Start the browser
154
135
browser = webdriver .Firefox (service = FirefoxService (GeckoDriverManager ().install ()))
155
136
browser .get ("https://www.nytimes.com/games/wordle/index.html" )
156
137
138
+ # Create the finder object (cf. class Finder)
157
139
finder = Finder ()
140
+
158
141
guesses_left = 6
159
142
160
143
# Wait for start
161
144
with keyboard .Listener (on_release = on_release , suppress = True ) as listener :
162
- print ("Starting" )
145
+ print ("Starting program \n " )
163
146
listener .join ()
164
147
165
148
# With "suppress=True", duplicate key presses are not sent to the application
@@ -169,18 +152,25 @@ def main():
169
152
# Get the game rows
170
153
game_rows = browser .find_elements (By .CLASS_NAME , 'Row-module_row__dEHfN' )
171
154
155
+ # Creators recommend “Slate” as starting word
172
156
first_string = "slate"
157
+
158
+ # Enter the first word
173
159
enter_word (first_string )
174
160
res = get_row_results (game_rows [0 ])
175
161
solving_algorithm (first_string , res , finder )
176
162
guesses_left -= 1
177
163
178
164
time .sleep (1 )
179
165
166
+ # Enter the next words
180
167
for i in range (guesses_left , 0 , - 1 ):
181
168
enter_word (finder .possible_words [0 ])
182
169
res = get_row_results (game_rows [guesses_left + 1 - i ])
183
170
solving_algorithm (finder .possible_words [0 ], res , finder )
171
+ if len (finder .possible_words ) == 1 :
172
+ print (f"The word is : { finder .possible_words [0 ]} \n " )
173
+ break
184
174
time .sleep (1 )
185
175
186
176
0 commit comments