We are The Imitation Game, a team consisting of BNTA Cohort 4 members, Alex, Cristian, Suad, Rosalinda, and Rachel.
- Introduction – project outline and Tech Stack
- Step-by-step instructions for initial set-up
- Project Structure
- Methods
- Using the API – HTTP Requests
This collaborative project was completed as part of the Bright Network Technology Academy programme. The project consists of a Wordle helper application, based on the concepts of information theory utilised in a YouTube video by 3Blue1Brown – Solving Wordle using Information Theory.
The API was created using Java, SpringBoot, and PostgresQL, and tested using Postman. The list of all possible words was taken from here, while the answers for each day's Wordle were found by inspecting the Wordle website.
There are two modes:
- The purpose of Helper mode is to help the user guess the five-letter word of the day in just a few tries!
- There is also a Competitive mode, including features that allow the user to create a user profile in the database, track their score against other users as well as against the machine, and to retrieve the average number of guesses it takes them to get the correct word.
Our project requirements and development schedule can be found here.
- Make sure that you have installed Java and PostgresQL.
- Clone this repository:
git clone [email protected]:https://github.com/Roscaaa/Wordle-Helper.git
and open in your favourite Java IDE (we recommend IntelliJ) - Create a new PostgresQL database called
wordle
. (If using the terminal, typepsql
to launch PostgresQL, and then runCREATE DATABASE wordle;
) - Use the
worlde.sql
script to populate yourwordle
database tables. To do this, you can either:- copy and paste each command individually, in sequence, using the terminal; or
- execute the entire sql script using Postico or similar database client
Note — the DROP TABLES commands at the beginning of the sql script are not necessary if setting up database for the first time (see below):
DROP TABLE IF EXISTS original_word_list CASCADE;
DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS actual_answers CASCADE;
DROP TABLE IF EXISTS all_games CASCADE;
Also Note — For the below commands, make sure to replace with the correct file paths:
-- Insert data into original word list table
COPY original_word_list (word, probability, score) FROM
'/[insert file path here]/initialcalculations.txt' DELIMITER ',' CSV;
-- Insert actual answers and respective dates data into actual answers table
COPY actual_answers (date_of_given_answer, actual_word) FROM
'/[insert file path here]/date-word-answer.txt' DELIMITER ',' CSV;
- Open Postman, and run the following HTTP request to populate the machine scores in the actual_answers table:
localhost:8080/competitive/computemachinescores
. Note that this stage may take some time, as it computes the machine scores for all of the ~3,000 actual answers!
See below for a list of methods used in each class and their descriptions:
This service class invokes the data access layer to retrieve Word
objects from the database. In addition, it also contains methods pertaining to the logic of the Wordle solver itself.
Return a list of all entries in the original_word_list table
as Word
objects.
Same as .GetAllWords
except the list of Word
objects is ranked
by the score property.
Same as .GetAllWordsRankedByScore
except the list of Word
objects has a
size given by numOfWords
.
Retrieves Word
with given id
from the
original_word_list table.
Retrieves first Word
whose word
property equals nameOfWord
from the
original_word_list table.
Returns true
if given string is included in the word column
in the original_word_list table, otherwise an exception is thrown.
Returns input list of Word
objects after
setting the probability property of each Word
to
all be equal and sum to unity. As an example a list consisting
of two Word
objects will be returned with probabilities
both set to 0.5
.
Returns a LinkedHashMap<String, String>
representing the
pattern obtained by guessing word
assuming targetWord
is the answer.
As an example, the Wordle pattern depicted here
would be represented by the map:
{
"f0": "yellow",
"o1": "yellow",
"o2": "green",
"d3": "grey",
"s4": "green"
}
In general, keys are denoted with the letter followed by the
index marking its position in the word. The values take three
values "yellow"
, "green"
and "grey"
each representing
the colour of the letter in the Wordle pattern.
Returns true
if word
and targetWord
can reproduce
pattern
when passed as arguments of the .GenerateWordPattern
method. Otherwise, false
is returned.
Returns a list of Word
objects consisting of the words in
wordList
that return true
when passed as the targetWord
argument of .checkPatternMatch
. Here guess
and pattern
serve
as the other arguments.
For a given guess
, compute a Double
whose value represents the
probability that the given pattern
is obtained. This is determined
through the sum of the probabilities of all Word
objects in
wordList
that give return true
when entered as the targetWord
argument for .checkPatternMatch
.
Returns the Double
whose value is the log base two of the argument.
Computes the average of the number of times one expects wordList
to be halved in size by guessing word
.
Applies the .computeWordScore
method to each Word
in wordList
and sets the score
property to the value returned by the method.
The resulting list of Word
objects is then returned.
Computes number of guesses taken for the Wordle solver to guess
answer
. The answer
is then returned with the machineResult
property set to the computed value.
This service class invokes the data access layer to retrieve and update
Answer
objects from the database.
Return a list of all entries in the actual_answers table
as Answer
objects.
Returns true
if Answer object with the id exists in actual_answers table
Returns Answer object with the corresponding id from actual_answers table
Takes Answer
object and adds to actual_answers table
Deletes Answer
object with corresponding id from actual_answers table from argument
Updates Answer
object with corresponding id from actual_answers table with Answer
object passed in argument
In this section, the POJOs used in the project are listed along with their properties and related JSON structure when using POST and PUT request:
HTTP Request | Type | Function |
---|---|---|
Word | • Integer ID • String Word • Double Probability • Double Score |
N/A |
User | • Integer ID • String Name • String Email • String Username |
{ "name": "Suad", "email": "[email protected]", "userName": "SusuTheFlowerPot" } |
Answer | • Integer ID • LocalDate DateOfAnswer • String AnswerOfDay • Integer MachineResults |
{ "dateOfAnswer": "2025-01-04", "answerOfDay": "waist", "machineResult": 3 } |
Game | • Integer ID • Integer UserId • Integer AnswerId • Integer UserGuesses |
{ "userId": 1, "answerId": 1, "userGuessed": 3 } |
The API can be used with the following HTTP requests, in the Postman desktop application:
HTTP Request | Type | Function |
---|---|---|
localhost:8080/helper | GET | Get all words. |
localhost:8080/helper/ranked | GET | Get all words ranked by score. |
localhost:8080/helper/ranked/{numOfWords} | GET | Get all words ranked by score and specify how many words returned. |
localhost:8080/helper/start | GET | Start the game. Will return best guesses ordered by score. |
localhost:8080/helper/start/{word} | DELETE | Input your guess for {word} and include the pattern that you got from Wordle in request body as JSON (i.e. which letters were green, yellow, grey). Example: { "f0": "yellow", "o1": "yellow", "o2": "green", "d3": "grey", "s4": "green" } |
localhost:8080/helper/endgame | DELETE | Ends game when you got the correct word. |
HTTP Request | Type | Function |
---|---|---|
localhost:8080/helper/wordbyid/{id} | GET | Get word by word id. |
localhost:8080/helper/wordbyname/{nameofword} | GET | Get word by word name. |
HTTP Request | Type | Function |
---|---|---|
localhost:8080/competitive/computemachinescores | PUT | Required to run as part of Competitive Mode setup. This will populate machine guesses in actual_answers table. |
localhost:8080/competitive/all | GET | Get all games in database. |
localhost:8080/competitive/addgame | POST | Add new game (JSON) to database using Request Body. Example: { "userId": 1, "answerId": 1, "userGuessed": 3 } |
localhost:8080/competitive/dailyresults/{date} | GET | Get all result on given date. |
localhost:8080/competitive/userresults/{username}/{date} | GET | Get all result on for username given date. |
localhost:8080/competitive/userresults/{username} | GET | Get all result on for username. |
localhost:8080/competitive/averageresults/{username} | GET | Get the average of a user's guesses. |
localhost:8080/competitive/start/{userId} | GET | Start a game for a user with matching id. |
localhost:8080/competitive/start/{userid}/{guess} | DELETE | Input the user's guessed in {guess}. Repeat for each guess until game is complete. |
localhost:8080/competitive/start/{userid}/end | POST | End game for user and save result to database. |
localhost:8080/user | GET | Get all users from database. |
localhost:8080/user/{userId} | GET | Get user from database by id. |
localhost:8080/user | POST | Add user (JSON) to database using Request Body. Example: { "name": "Suad", "email": "[email protected]", "userName": "SusuTheFlowerPot" } |
HTTP Request | Type | Function |
---|---|---|
localhost:8080/competitive/{id} | PUT | Update game (JSON) by id through Request Body. Example: { "userId": 1, "answerId": 1, "userGuessed": 3 } |
localhost:8080/competitive/{id} | DELETE | Delete game by id. |
localhost:8080/competitive/{id} | GET | Get game by id. |
localhost:8080/answers | GET | Get all answers. |
localhost:8080/answers/{id} | GET | Get an answer by answer id. |
localhost:8080/answers/addanswer | POST | Add answer (JSON) using Request Body. Example: { "dateOfAnswer": "2025-01-04", "answerOfDay": "waist", "machineResult": 3 } |
localhost:8080/answers/{id} | DELETE | Delete answer by id. |
localhost:8080/answers/update/{id} | PUT | Update answer (JSON) by id using Request Body. Example: { "dateOfAnswer": "2025-01-04", "answerOfDay": "waist", "machineResult": 3 } |
localhost:8080/user/{userId} | DELETE | Delete user by id. |
localhost:8080/user/{userId} | PUT | Update user (JSON) by id using Request Body. Example: { "name": "Suad", "email": "[email protected]", "userName": "SusuTheFlowerPot" } |
A huge thanks to the BNTA team, and especially to our trainers, Colin, Nelson, and Iain!