Course:CPSC312-2024-wordle

From UBC Wiki

Authors: Julian Kennedy, Ilya Patrzykat

What is the problem?

Our goal is to create a functional Wordle game in Haskell.

Basic features will include:

  • Implement standard Wordle rules (6 guesses, 5 letter words)
  • Random word from word list will be chosen each game
  • Correctly process user input for each guess and provide appropriate output. Green (correct letter and position), yellow (correct letter but wrong position), and gray (letter not present in word).

What is the something extra?

We will be implementing the optimal solver created by 3Blue1Brown, using Information Theory. In a general sense, the approach aims to minimize the number of guesses needed by strategically maximizing the amount of information gained with each attempt. Once the user has finished their game of Wordle, we will display our optimal solution.

The idea is that we essentially start with a list of all possible words and analyze the placement of each word's letter placement and frequency in known English words. Then, we calculate the "entropy" of each word based on how much it reduces the possible remaining words after you guess. Choosing the word with the highest entropy means that we eliminate the most possibilities, while providing information about the hidden word. We then repeat these steps for each future guess, based on the information gained from the previous guesses.

What did we learn from doing this?

(This should be written after you have done the work.) What is the bottom-line? Is functional programming suitable for (part-of) the task? Make sure you include the evidence for your claims.

We learned about the versatility of Haskell, specifically how well-suited it is for making games, such as Wordle. More specifically, we learned about how to create larger programs in Haskell, how to design code to be functional and recursive, how to take in input and display output, and how to error handle. In regard to creating larger programs, Haskell is good because it requires smaller, more modularized functions, which allowed us to focus on each aspect of the game separately and we could test each feature individually. In addition, since Haskell is a functional language, we started with writing the code in Python, a language we are more comfortable and familiar writing in and then we converted it all to Haskell. However, the Python code was not always easily transferrable to Haskell due to the functional aspect of Haskell. So, after we wrote working code, we went back through the code and modularized it and created simple, recursive functions where possible to remove the use of loops and create functional code. This made the transition to Haskell code much smoother, and it was easier for us to wrap our heads around the implementation. We also learned how to take in input and display output using do blocks and IO Strings. This taught us the difference between IO and non-IO types and how to convert IO Strings to non-IO Strings so that we could work with the user input. We also learned about error handling and how to deal with user input to account for things such as when the user deletes a character and when the user inputs an invalid string.

Bottom-line, we learned a lot and doing this project gave us a better understanding of the capabilities of Haskell. Making the code functional was suitable for this task, especially considering the parts of the Wordle game and optimization could be easily broken down into modularized and simple functions. We also got practice writing more Haskell code and we both feel that we have a much stronger understanding of the language now than before we started the project.

Work division

How was the workload divided? Who did what? (This can be in a private communication to the TA if you do not want it to be public).

The work was divided equally. We contributed to the codebase together using Live Share on VSCode.

Links to code etc.

Link to 3Blue1Brown video: https://www.youtube.com/watch?v=v68zYyaEmEA

Link to code: patrzykat/wordle (github.com)