Wordle Bot

January 25, 2022  |  7 minutes to read


Update: I've since turned off this bot since it became too toilsome to update every time Wordle made changes to its UI 😓

Like everyone else, I’ve been obsessed with Wordle lately.

I was really bad at it when I began. My original strategy was to use the first 3 or 4 guesses to uncover as many letters as possible, and then use the last few guesses to unscramble the solution. This turned out to be a terrible approach, and I failed most of the challenges.

This got me thinking: what is the optimal Wordle strategy?

And that immediately led to a second thought: can I automate it?

The answer is a resounding of course! I present to you: Wordle Bot!

The Wordle Bot logo


How it works

The general strategy is to repeatedly pick the word that is most likely to reveal new letters. To do this, I use the frequency of each letter in the set of possible solutions to assign a score to each potential guess, and choose the option with the highest score.

The set of all possible solutions is conveniently hardcoded in Wordle’s source code, so my first step is to simply hardcode this list into my own script.

Next, I loop through each potential solution and count how many times each letter occurs. This results in a mapping like this:

{
  "e": 1233,
  "a": 979,
  "r": 899,
  "o": 754,
  "t": 729,
  "l": 719,
  "i": 671,
  "s": 669,
  "n": 575,
  "c": 477,
  "u": 467,
  "y": 425,
  "d": 393,
  "h": 389,
  "p": 367,
  "m": 316,
  "g": 311,
  "b": 281,
  "f": 230,
  "k": 210,
  "w": 195,
  "v": 153,
  "z": 40,
  "x": 37,
  "q": 29,
  "j": 27
}

So, for example, a word like “HELLO” would score 3,814 (389 + 1,233 + 719 + 719 + 754).

Using this method, the bot would always start with the word “EERIE”, due to its high score of 5,269 (1,233 + 1,233 + 899 + 671 + 1,233).

However, this actually isn’t a very useful guess! It only gives us information about 3 letters. A more strategic method is to pick the highest scoring word that contains no repeating letters. Using this approach, the best first play is “LATER”, which still scores quite high (4,559 = 719 + 979 + 729 + 1,233 + 899) and provides information about 5 different letters.

(Side note: Even though I know I should start with “LATER” when playing on my own, I can’t help but start with “ADIEU” - too many vowels to pass up!)

Each subsequent guess is generated using the same algorithm, except that the list of possible solutions is shrunk by eliminating all options that contradict the results of previous guesses. A side effect of this elimination method is that it effectively plays the game on Hard Mode. (Hard Mode = “Any revealed hints must be used in subsequent guesses”).

In later guesses, it’s possible there won’t be a valid option that includes no repeating letters, so in this case the bot falls back to the highest-scoring word regardless of letter repetition.

Demo

Here’s an example of the script working in bookmarklet form:

A demo of Wordle being solved by the script in bookmarklet form

(Instruction for setting up this script as a bookmarklet can be found here.)

How good is it?

The short answer is: quite good! (Much better than me.) But not perfect!

At the time of writing, Wordle Bot has solved 220 puzzles. Its guess distribution looks like this:

A chart showing Wordle Bot's guess distribution

80% of the time, Wordle Bot can solve the daily puzzle in 4 tries or less. Not bad!

But why isn’t it perfect? I was intrigued by the two puzzles it failed to solve. In both cases, Wordle Bot failed in a similar fashion. By guess 3, it had nailed down letters 2 - 5. It spent the remaining guesses cycling through different starting letters, and failed to find the correct one before it ran out of guesses.

Here is its attempt at puzzle 113:

A screenshot of Wordle Bot's solution to puzzle 113
Wordle 113

Even though the correct solution (“HATCH”) scores higher than all the options it tried (“PATCH”, “MATCH”, “BATCH”, and “WATCH”), it chose not to guess “HATCH” since it includes a repeated letter (“H”). As mentioned earlier, the algorithm always prefers guesses without repetition if they exist.

A similar thing happened on day 123:

A screenshot of Wordle Bot's solution to puzzle 123
Wordle 123

In this case, the solution “JAUNT” scored lower than all the options it tried (“DAUNT”, “HAUNT”, “GAUNT”, and “VAUNT”), so it simply ran out of time.

Bringing the bot to life

Turning the script into a Twitter bot was just a matter of automation.

First, I built a Puppeteer script to launch Wordle in an instance of headless Chrome, inject my bookmarklet script, and solve the puzzle. Once it’s finished, the script takes a screenshot, uploads it to Imgur, and tweets the results:

Then, I configured a scheduled GitLab pipeline to run the project’s pipeline every day at 3:00 AM ET.

Even though the end result is fairly simple, I ran into a number of speed bumps along the way:

  • Wordle shares its results by copying them to the clipboard, but I couldn’t figure out a way to access the clipboard’s contents inside Puppeteer (it always returned my system clipboard contents instead). To get around this, I had to build the “share” text myself.
  • The Imgur JavaScript library I use required Node 14+, but the Puppeteer Docker image I was using inside my GitLab pipeline was stuck on Node 12. Switching to buildkite/puppeteer fixed this.
  • The pipeline would randomly fail while trying to connect to the Wordle website: Error: net::ERR_NETWORK_CHANGED at https://www.powerlanguage.co.uk/wordle/. I “solved” this by adding a timeout and retry to my GitLab job.

Absurdal

Oh, did I mention the bot is also surprisingly good at solving the Absurdal variant?

A demo of Absurdal being solved by the script in bookmarklet form



Other posts you may enjoy:

GitLab Pages with multiple domains

October 14, 2024  |  3 minutes to read

Zoom light

May 31, 2024  |  6 minutes to read

I built a weird keyboard

June 26, 2023  |  14 minutes to read

Herding Gits

August 26, 2021  |  2 minutes to read

It's finally here! 🎉

May 7, 2021  |  1 minute to read