Unsurprisingly, Wordle is a game about words, so we need to have a section of the code dedicated to them.
DAILY
Each day the players are allowed to guess a single word which is automatically selected by the script.
I didn’t want to make a fully functioning Wordle clone with a vast set of words, so the set here is quite small and is stored in a single string. The words are base64-encoded to obfuscate the words from people seeing the code like yourself.
%%[
/* Select the word for the day in the encoded form */
set @words = 'U1RFQU0=|T1BFUkE=|Q0xPQUs=|Q0xFQVI=|TklHSFQ=|R0hPU1Q=|U1RBRkY=|U1RPVVQ=|UElMT1Q=|S0VCQUI=|QUJZU1M=|Uk9VR0U=|V09STEQ=|UVVFUlk=|VUxDRVI=|U0lFR0U=|QkxPS0U=|RlJBTUU=|Q0hFQVQ=|RVBPQ0g=|U1BJQ1k=|RUxERVI=|RkVJR04=|Q1JBVEU=|VElNSUQ=|U1BJTEw=|QlJFQUs=|UEFVU0U=|R1JJTUU=|Q0hBTVA=|TllNUEg='
set @rowset = BuildRowsetFromString(@words, '|')
set @day = DatePart(@now, 'D')
set @row = Row(@rowset, @day)
set @theWordEncoded = Field(@row, 1)
set @theWord = Base64Decode(@theWordEncoded, "UTF-8")The processing is quite simple:
- We use the
BuildRowsetFromString()function to make our string work as an array of words - We get the number representing the
@dayof the month - This number is used to select the corresponding row from our
@rowsetof words) - The encoded word is retrieved using the
Fieldfunction - Finally, we decode the string obtained in the last step to get the daily word
Consider this example:
- I’m writing this on April 12 2022
- This means the
@dayvariable would get the value of 12 - The 12th word is
Uk9VR0U=which decoded means ROUGE
VOCAB
To ensure players don’t submit non-existing words to easily find the letters from the searched word, we need to have a data extension with a list of allowed words:
- I’m using the
Wordle - Allowed Word Listname in my script - The DE has just a single column called
Wordswith the obvious text data type and length of 5 characters - You can see the allowed word list here – this txt file stores 12.972 words
NOTE Why do we need this? We want to prevent players from optimizing their search for the daily word by using strings like EAIOU or NRSTC allow them to eliminate letters without flexing their knowledge of the English vocabulary.
CHECK
If the player has submitted a word, we perform a validation to see if we can accept this @lastGuess.
Words are accepted if they fulfill the following conditions:
- they were not submitted before
- they exist in our dictionary data extension
/* Validation of incoming words*/
IF
IndexOf(@guesses, @lastGuess) < 1
AND
Empty(@lastGuess) == false
THEN
set @lookup = RowCount(LookupRows('Wordle - Allowed Word List', 'Word', @lastGuess))
IF
@lookup == 1
AND
Empty(@guesses) == true
THEN
set @guesses = @lastGuess
ELSEIF
@lookup == 1
AND
Empty(@guesses) == false
THEN
set @guesses = Concat(@guesses, '|', @lastGuess)
ELSE
set @feedback = Concat("'", @lastGuess, "' is not an allowed word")
ENDIF
ELSEIF
IndexOf(@guesses, @lastGuess) > 0
THEN
set @feedback = 'Repeat guesses are not allowed'
ENDIFSubmitted words are validated in two ways:
- we check if they exist in our data extension with allowed words
- if the word is found by the
lookupRowsfucntion, the@lastGuessvariable is added to the@guessesstring conditionally:- if it is the first submitted word, it becomes the
@guessesvalue - any words submitted later are delimited with the
|separator
- if it is the first submitted word, it becomes the
- if the word is found by the
- we check if the word was submitted previously
INPUT
You might have thought that there’s a flaw in the validation of the submitted word – the submitted @lastGuess is never checked for length or if it only contains letters. That part of the validation is done entirely client-side by HTML form validation and the properties of the main input.
The submited word needs to fit with the [A-Za-z]{5} pattern: must have 5 letters (case insensitive). If the input value does not match this value, the browser will display the message: This needs to be a 5-letter word.
RESET
The following block checks if the daily word has expired in the middle of our session:
/* Check if the last word has expired */
IF
Empty(@previousWord) == false
AND
@theWord != Base64Decode(@previousWord)
THEN
set @feedback = 'The daily word has reset'
set @guesses = ''
set @lastGuess = ''
ENDIF
While the script is running, we check if the current run is a reaction to a form submission event (the @previousWord values is not empty) and later compare the current daily word with the one that was submitted in the @previousWord in the encoded form. If those conditions are met:
- we remove all
@guesseswhich resets the progress - the
@lastGuessis removed so that a lucky guess from the last try does not accidentally count as a submission for a new day
