# Why & How I automated Wordle


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/](https://www.powerlanguage.co.uk/wordle/)

Below is a working video of my code 

%[https://youtu.be/Q1omD5VPLPY]


If you just want to use it, you can go to https://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

```powershell
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

 

```java
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

```java
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. 

```java
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](https://github.com/CODINGSAINT/wordle-solver/blob/main/src/main/java/Main.java)
