Wordle-player - An optimal player for Wordle. Based on a rough understanding of information theory

Overview

Wordle Player

Just for fun, my attempt at making an optimal player for Wordle. Based on a rough understanding of information theory, and the idea that the best guess for a given turn is the one that gives you the most information.

Usage

wordle.py will feed you the guesses for a game of Wordle. If you run python wordle.py, you'll be launched into an interactive session, where the program outputs guesses and you just need to give it the outputs of each guess. Here's an example session where the word was PIANO:

$ python wordle.py
> TARES (15918 words)
? .y...
> ALOIN (999 words)
? y.yyy
> OMINA (5 words)
? y.ygy
> PIANO (1 words)
? ggggg

User input occurs on the lines starting with ?. Each . represents a letter that isn't in the word at all, a y represents a letter that is in the word but in the wrong place, and a g represents a letter in the right place. Along with the guess, the program outputs the number of words remaining that it can choose from.

The default wordlist has some pretty obscure words in it, which might not be valid for your game of Wordle. If so, just enter a blank line to fetch the next-best guess:

$ python wordle.py
> TARES (15918 words)
? .y...
> ALOIN (999 words)
? 
> ANOIL (998 words)
? 
> ANOLI (997 words)
...

You can also play with other word sizes using the -k flag:

$ python wordle.py -k 11
> PERCOLATING (37539 words)
? .yy.y.gggy.
> ENUMERATION (29 words)
...

Background: Entropy

From information theory, the entropy H(X) of a random variable X with n possible events is defined as:

H(X) = -sum{ P(x_i) * log2(P(x_i)) } for 1 <= i <= n

H(X) roughly means the amount of information* it takes to describe the outcome of X. For example, the entropy of a fair (50/50) coin flip is

H(fair coin) = -[1/2*log2(1/2) + 1/2*log2(1/2)] = 1.

But the entropy of flipping a horribly weighted coin is

H(unfair coin) = -[1/10*log2(1/10) + 9/10*log2(9/10)] = 0.47.

The fair coin takes exactly 1 bit to describe one of two outcomes, which makes sense. A flip of the unfair coin takes less information to describe because the same thing happens most of the time, and every now and then you'll need some extra bits to describe the more unlikely event.

*Measured in bits, since we use log2 - you can use any base you want, though.

Modeling a game of Wordle

Let's assume that every "target" word in Wordle is equally likely (drawn from a dictionary of k-letter words). When we play some word w, we get some outcome (in the form of each letter being green, yellow, or gray) - this will be our random variable X_w. By carefully choosing the word we play, we get different expected outcomes for X_w, and thus get different entropies. It's kind of like choosing the weights of our coin toss, but for a much more complex event. Our goal is to find the w that maximizes H(X_w), in order to make sure that when we observe the outcome, we gain as much information as possible.

To calculate H(X_w), we can check each possible target word in the dictionary and see what the outcome of playing w gets. There are 3^5 = 243 possible outcomes (different combinations of green, yellow, and gray), and each of these will get an associated probability depending on how many target words they map to. Calculating H(X_w) is then straightforward, we can use the formula from earlier:

H(X_w) = -sum{ P(r) * log2(P(r)) } for each possible outcome r.

Now we've chosen a word to play. When we play it, we'll observe the outcome of X_w. This will eliminate many words from our dictionary - we can throw out any word that wouldn't have lead to the observed outcome. Doing this iteratively should eventually lead to us either guessing the target word or leaving exactly 1 word in the dictionary.

Speed

This will work to find the optimal word, but it's an expensive calculation: given a dictionary with n words with k letters each, this will take O(k * n^2) time to run. I'm lazy so I wanted to find a fast approximation.

Instead of playing an entire word at a time, we can play a single character c in position i and observe its outcome Y_ci. Then, we can estimate H(X_w) by adding H(Y_ci) for each character of w. Now, this would give us exactly H(X_w) if each of Y_ci were independent random events, but this obviously isn't the case - for instance, there are way more words that start with SH___ than words that start with HS___. (Following this strategy to calculate H(X_w), the optimal starting word I got was SAREE, which isn't a great starter because it has two of the same letter. Playing E anywhere is a high-entropy play, because it's a very common letter.)

So instead, we can use this estimate as a filter, and just calculate the actual value of H(X_w) for the top a% of words. Using this strategy with a = 3, the optimal starting word I got for 5-letter words was TARES. I precomputed all of these for between 4 and 11 letters and saved them in starting_words.pickle. The wordle.py program uses these by default.

Pseudocode

k := number of letters per word
D := dictionary of k-letter words
a := the retry percentage we choose
H := the entropy function, which takes a distribution and returns its entropy

function guess(W) {
    n = size of W

    -- H(Y_ci)
    HY := empty map of (char, number) -> number
    for each c in the alphabet:
        for each i in [0, k):
            Y := map of possible outcomes (green, yellow, or gray) -> 0
            for each t in W:
                r := the outcome of playing c in position i on target word t
                Y[r] += 1/n
            HY[(c, i)] = H(Y)

    -- Estimated H(X_w)
    EHX := empty map of string -> number
    for each w in D:
        EHX[w] = sum of HY[(w[i], i)] for i in [0, k)
    
    -- Eligible words
    D' := a% of words in D with the highest EHX[w]

    -- Actual H(X_w)
    HX := empty map of string -> number
    for each w in D':
        X := map of possible outcomes -> 0
        for each t in W:
            r := the outcome of playing w on target word t
            X[r] += 1/n
        HX[w] = H(X)
    
    return the word in D' with the maximum HX[w]
}

References

Owner
Neill Johnston
Neill Johnston
Memory game in Python

Concentration - Memory Game Concentration is a memory game written in Python, inspired by memory-game. Description As stated in the introduction of th

Marco Colonna 0 Jul 21, 2022
WIP python/pygame 2D zombie shooter

2d-shooter project A single/multiplayer co-op survival small space zombie shooter. If you'd like to contribute, feel free to join the discord! INSTALL

36 Dec 08, 2022
A stat tracker for the bedwars hypixel game in python

A hypixel bedwars stat tracker. Features Get stats in your current lobby Get stats in a guild Installation & Configuration git clone https://github.co

Le_Grand_Mannitout 3 Dec 25, 2021
Made with pygame. Multiplayer game using socket module and threading.

Rock Paper Scissor made with python-pygame. Poorly made, as a beginner in programming. Multiplayer with server code and client code provided.

AllenJo 1 Dec 29, 2021
A small fun project to simulate Conway's Game of Life, created in Python.

A small fun project to simulate Conway's Game of Life, created in Python. Conway's Game of Life simulates a grid of cells, where the state of each cell consists of whether the cell is alive or dead.

Harrison Verrios 1 Jun 19, 2022
Découvrez CubeCraft Launcher, une application uniquement codé en Python et en Batch

Découvrez CubeCraft Launcher, une application uniquement codé en Python et en Batch. Grâce à son interface graphique facile et intuitive, vous pouvez vous retrouver facilement.

1 May 21, 2022
A program to read, edit, and write save files for the game Railroads! Online

RROSE - v0.3.6 This program is intended to be used as an external tool to Railroads Online server hosts. It will read save files, allow to modify entr

17 Dec 09, 2022
SnailJumper - A game that is developed as an assignment for Computer Intelligence course

Snail jumper Neuroevolution game assignment. Fall 2021 - Computer Intelligence.

Soroush Mehraban 22 Aug 22, 2022
A small Python Library to process Game Boy Camera images

GameBEye GameBEye is a Python Library to process Game Boy Camera images. Source code 📁 : https://github.com/mtouzot/GameBEye Issues 🆘 : https://gith

Martin TOUZOT 4 Nov 25, 2022
Tic-Tac-Toe Game in python3 Tkinter

Tic Tac Toe Tic-Tac-Toe Game in python3 Tkinter About: Tic Tac Toe or Noughts and Crosses as called in British is a pencil and paper game for two play

Sai Swarup Yakkala 5 Nov 06, 2022
Datamining of 15 Days of (free) Games at the Epic Games Store (EGS).

EGS: 15 Days of Games This repository contains Python code to data-mine the 15 Days of (free) Games at the Epic Games Store (EGS). Requirements Instal

Wok 9 Dec 27, 2022
It just a cli based snake game written in Python.

Snake Game in Python Things that I learned in this project: OOP in Python. Clean code. The curses library. How to run the game You need to clone this

Kevin Marques 7 Oct 01, 2022
PLVRA is a TUI (Terminal User Interface) implementation of wordle / termo in portuguese, written in Python

PLVRA is a TUI (Terminal User Interface) implementation of wordle / termo in portuguese, written in Python

Enzo Shiraishi 1 Feb 11, 2022
A basic quiz game using Python

QuizGame A basic quiz game using Python Passwords for quizzes (NO CAPS LOCK!): -ryzermattishandsome -canisleepwithyou Before using this, please make s

Austin 1 Nov 12, 2021
This is an interactive MiniMap made with Python, PyQT5 & Pytesseract for the game

NWMM-New-World-MiniMap Features: Automatically grabs position from "New World" Instance Live visualisation of player position on MiniMap Circular & re

Nezzquikk 18 Sep 21, 2022
A script to install a Windows game through GOG on Linux

proton-gog-install A script to install a Windows game through GOG on Linux. Based on this gist. Tested on Arch, might work elsewhere. Requirements: Im

5 Dec 28, 2022
QuizGame is a quiz with different topics. You can choose a topic and take the quiz

QuizGame is a quiz with different topics. You can choose a topic and take the quiz. In the end you will get your result. The program is under active development, so there may be errors or flaws in it

Lev Likhachev 2 Nov 12, 2021
PyCheckers - A classic board game implemented in pygame

PyCheckers! A classic board game implemented in pygame! Complete with every feature you need to play checkers! (including handsome sprites drawn by a

helaxious 1 Jan 21, 2022
A minecraft bedrock server software written in python (3.X)

Podrum README also available in: English 🇺🇸 Français 🇫🇷 Deutsch 🇩🇪 Español 🇪🇸 Tiếng Việt 🇻🇳 Italiana 🇮🇹 Русский 🇷🇺 中文 🇨🇳 Is a Minecraf

Podrum 53 Nov 11, 2022
3D online shooter written on Panda3D 1.10.10 and Python 3.10.1

на русском itch.io page Droid Game 3D This is a fresh game that was developed using the Panda3D game engine and Python language in the PyCharm IDE (I

Marcus Kemaul 5 Jun 04, 2022