Since my husband and I moved to the United States and gained access to public library resources, we have been unable to stop playing Wordle. Although the rules are simple, the game poses a significant challenge to both native English speakers and bilinguals, which explains its popularity in our home. While I am a big fan of word games, anyone passionate about enhancing and expanding their vocabulary has a chance in this game.
I want to express my great appreciation to
for the job he did in his article "Playing Wordle in R," as it helped for inspiration and consultation. You can see the resulting code on GitHub.The rules of the game, according to the New York Times website, are the following:
Guess the wordle in x attempts.
Each guess must be a valid 5-letter word.
The tiles' colors will change depending on how close your guess was to the answer. They will be green if the letter is in the word and the correct spot, yellow if it is in the word but the wrong spot, and grey if it is not in the word at all.
To code Wordle, I divide the program into four functions:
ChooseWord = Generates a random word from a word list.
I found three different word lists and merged them into one, which you can find on GitHub. Initially, I imported these three lists into my code: a five-letter word list, MIT’s number one word list, and the 10,000 most common English words according to Google’s Trillion Word Corpus. However, I decided to merge, filter, and clean the words in Excel beforehand to import just one list into my code.
Before importing and reading a .xls document, make sure you have installed the package tidyverse or readxl and the library readxl.
library(readxl) ChooseWord <- function(answerLength){ #Imports word list filePath <- "/Users/khadijah/CODE PROYECTS/R PROYECTS/WORDLE/wordleWordList.xls" wordDataBase <- toupper(unlist(read_xls(filePath, col_names = F, .name_repair = "unique_quiet")))
randomWord <- sample(wordDataBase, size = 1, replace = T) return(randomWord) }
ApproveInput = Detects errors that users may make when submitting an attempt, such as submitting invalid characters (like numbers), wrong length, or an invalid word. It is still pending to include what prevents the user from submitting a word that does not follow the previous hints. For example, if you guess “noise” and it indicates that the “o” is not in the word, the next guess cannot include an “o,” making the game significantly more challenging. Also, to detect if the answer is valid, I use the word list database to check whether the word is real. This limits the amount of words you can submit to the list you are using.
ApproveInput <- function(guess, guessLength, guessVec, answerLength, controlVar){ #Recovers word list for evaluation filePath <- "/Users/khadijah/CODE PROYECTS/R PROYECTS/WORDLE/wordleWordList.xls" wordDataBase <- toupper(unlist(read_xls(filePath, col_names = F, .name_repair = "unique_quiet"))) #Checks characters for (i in 1:guessLength) { if (!(guessVec[i] %in% LETTERS)){ errorChar <- print("Your answer must only include letters") controlVar <- F return(controlVar) } } #Checks Length if (guessLength != answerLength){ if (guessLength < answerLength){ errorLengthL <- print("Your answer is shorter than 5 letters") controlVar <- F } if (guessLength > answerLength) { errorLengthM <- print("Your answer is longer than 5 letters") controlVar <- F } return(controlVar) } #Checks for a valid word if(controlVar == T){ if(!(guess %in% wordDataBase)){ errorWord <- print("Your answer is not a real word. If you really think this is wrong, update the database. Meanwhile, try with a different word.") controlVar <- F } } return(controlVar) }
CheckAnswer = Evaluates the user's attempt.
This is relatively straightforward. Each letter of the word is compared to the answer, and the evaluation is returned. Because this is a beginner project, we will not use fancy colors here. Instead, we will use a "-" for letters that are not in the answer, a "Y" for a letter that is out of place, and a "G" for the letter in the correct position.
CheckAnswer <- function(guessVec, wordDay){ gradeVec <- c(rep("-", 5)) answerLength <- length(wordDay) for (i in 1:answerLength){ if(guessVec[i] == wordDay[i]) { gradeVec[i] <- "G" wordDay[i] <- "-" #Removing the letter ensures there are no mixups with Yellows } } for (i in 1:answerLength){ if(gradeVec[i] != "G"){ if(guessVec[i] %in% wordDay){ gradeVec[i] <- "Y" wordDay[match(guessVec[i], wordDay)] <- "-" } } } return(gradeVec) }
PlayGame = Counts the number of attempts and ends the game after x rounds.
Here, you can see I chose to end the game after five lost attempts. Nevertheless, you can make this game as long as you desire! Wordle rules use five-letter words and up to six rounds. To facilitate the user’s interaction with the interface, I print the user's guess, the letters that have not been used, the evaluation, and the rounds. If the user's guess does not pass the test of ApproveInput(), the game does not continue unless a valid attempt is submitted. Who does not hate it when you miss an opportunity due to a typing mistake?
PlayGame <- function(randomWord, rounds = 5, answerLength = 5){ #Random word randomWord <- ChooseWord(answerLength) wordDay <- strsplit(randomWord,"") [[1]] #Round counter guessNo = 1 lettersLeft <- LETTERS #Display letters guessVec <- c(rep("-", answerLength)) #Condition to not lose while (guessNo < rounds + 1) { #Asks the user to submit a word and converts it to a vector. print(paste(c("Letters left: ", lettersLeft), collapse = " ")) guess <- toupper(readline(paste("Make you guess number", guessNo, ": "))) guessLength <- nchar(guess) guessVec <- unlist(strsplit(guess, "")) #Evaluates ###Ends the game if the user's guess is identical to the Word of the Day if(identical(guessVec, wordDay)){ print("Wow, YOU WON") return() } else{ #Checks input controlVar <- T controlVar <- ApproveInput(guess, guessLength, guessVec, answerLength, controlVar) while(controlVar == F){ guess <- toupper(readline(paste("Make you guess number", guessNo, ": "))) guessLength <- nchar(guess) controlVar <- T #The round will not continue unless the word does not contain mistakes guessVec <- unlist(strsplit(guess, "")) controlVar <- ApproveInput(guess, guessLength, guessVec, answerLength, controlVar) } #Evaluates guess gradeVec <- CheckAnswer(guessVec, wordDay) guessNo = guessNo + 1 #Updates letters left, prints user's guess and the evaluation lettersLeft <- setdiff(lettersLeft, guessVec) print(paste(strsplit(guess, "") [[1]])) print(gradeVec) } } if (guessNo == rounds + 1) { print(paste("No more chances left. You have lost. The word was:", randomWord)) } }
That is everything you need to start playing Wordle on your own. I hope this manual has been helpful to you. Now lets see how the program works:
> source("~/CODE PROYECTS/R PROYECTS/WORDLE/wordle.R")
[1] "Letters left: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
Make you guess number 1 : noise
[1] "N" "O" "I" "S" "E"
[1] "-" "-" "Y" "Y" "-"
[1] "Letters left: A B C D F G H J K L M P Q R T U V W X Y Z"
Make you guess number 2 : silky
[1] "S" "I" "L" "K" "Y"
[1] "Y" "G" "-" "-" "-"
[1] "Letters left: A B C D F G H J M P Q R T U V W X Z"
Make you guess number 3 : visit
[1] "V" "I" "S" "I" "T"
[1] "-" "G" "Y" "-" "-"
[1] "Letters left: A B C D F G H J M P Q R U W X Z"
Make you guess number 4 : birds
[1] "B" "I" "R" "D" "S"
[1] "-" "G" "G" "-" "G"
[1] "Letters left: A C F G H J M P Q U W X Z"
Make you guess number 5 : firms
[1] "Wow, YOU WON"