Wordle has taken over the world trend. I feel the simple interface and no extra advertisement have made it successful. Without advertisements, you can focus on the problem, and each answer you give acts as a clue for the next one.
More than being an interesting game it is unique problem as a programmer. The problem has already been solved over the years but yet a good exercise to practice filters. If you are not aware of the wordle game let’s look at its rules and understand the game first.
What is Wordle
A simple game, where you have to guess 5 letter words in 6 attempts. Once you enter the first guess word, there are two possibility
- You guessed the correct word.
- You guessed the wrong word.
If you guessed the correct one, the game is over for the day. You can come again the next day and try a new word to guess.
If you guessed wrong, there are 3 possibilities again
- Character in present and at the correct place
- Character is present but in the wrong place
- Character is not absent in the word
The above three are the clue for you to guess the next word. You can play the game at https://www.powerlanguage.co.uk/wordle/
Below is a working video of my code
If you just want to use it, you can go to github.com/CODINGSAINT/wordle-solver, and clone the repo
It requires
- Java 17
- maven
run it
With Java 17+ and maven installed, run the following commands for magic
mvn clean install
java -jar .\target\wordle-1.0-SNAPSHOT-jar-with-dependencies.jar
How to solve it
We require the list of 5 letter words as database. Now if we see the pseudo code , it should be as following
1. while (correct word is found){
2. pick a random word from database
3. evaluate word
4. if not correct
5. filter words
5.a - remove all of the words whose character are not present in database
5.b - pick all words has the present character from current word
5.c - pick those whose character are at correct place
5.d - update words database
go to step 2
if word is correct exit
}
I wanted to solve it , so I looked at my go-to language, java - You can use any language of your choice, all you require is a framework that can open a web browser and key in for your tests. I have used Microsoft Playwright
.
Let's create 3 important buckets for keeping present characters, absent characters, and a map for position and characters at a place
static List<Character> notPresent =newArrayList<>();
static List<Character> present =newArrayList<>();
static Map<Integer, Character> atPos =newHashMap<>();
Let’s look at the most important filter logic below
static Predicate<String> filter() {
//Remove all present fom notPresent and contails - Because of double letter words
notPresent.removeAll(present);
notPresent.removeAll(atPos.values());
return s -> {
boolean np = notPresent.stream().allMatch(character -> s.indexOf(character) < 0);
if (!np) return false;
boolean p = present.stream().allMatch(character -> s.indexOf(character) >= 0);
if (!p) return false;
Boolean positionVerified = true;
Set<Integer> set = atPos.keySet();
for (Integer pos : set) {
if (s.charAt(pos) != atPos.get(pos)) {
return false;
}
}
return true;
};
}
We need to evaluate each word from the list of words and update our Lists of notPresent, present, and map of position and character.
static Integer evaluate(Page page, String word, int row) {
var elements = page.querySelectorAll("#board game-row:nth-child(" + (row) + ") game-tile");
var results = elements
.stream().map(e -> e.getAttribute("evaluation")).toList();
if (results.size() == 0)
return null;
Integer exactMatch = 0;
for (int i = 0; i < results.size(); i++) {
String currentResult = results.get(i);
if (currentResult == null) return null;
switch (currentResult) {
case "present" -> present.add(word.charAt(i));
case "absent" -> notPresent.add(word.charAt(i));
case "correct" -> {
exactMatch++;
atPos.put(i, word.charAt(i));
}
}
}
return exactMatch;
}
This method will return 5 if all of the evaluated characters are correct.
If you are interested in the full program, check it at https://github.com/CODINGSAINT/wordle-solver/blob/main/src/main/java/Main.java