Utilize Python and Rich to Create a Wordle Clone
We'll create a Wordle clone for the terminal using this tutorial. Millions of people have used Wordle since Josh Wardle first released it in October 2021. Although the original game may be played online, we'll create a command-line application for our version and utilize the Rich library to give it a good appearance.
You will gain experience setting up a basic prototype game and iteratively developing it into a reliable application as you work through this step-by-step project.
What is Wordle?
Wordle gives you six attempts to find a five-letter word that is buried. After each guess, you will be informed which letters are correctly inserted, misplaced, and incorrect.
Step 1: Word Guessing
The game won't look good, and it will be challenging to interpret the player's feedback. However, the foundation for your Wordle clone will already be in place. You'll construct a very straightforward word-guessing game in this step.
Your users can make educated guesses about words and learn which letters they put correctly, which letters they put in correctly, and which letters aren't even in the word.
You'll use input() to read the words the players have provided, a for loop to give them numerous guesses, and sets to track the letters they properly identified in this stage.
Obtain user data through the input ()
With user input, you can obtain information from them (). This in-built feature is a fantastic way to offer straightforward interactivity on the command line.
Launch your REPL and try it out. You should write:
You can ask for input using an optional prompt (). Before entering any data, the user will see this. The highlighted line in the example above displays both the user input and the prompt. The user is prompted to make a word guess. The user types "python" and clicks "Enter."
The call to input returns the user's text entry (). The case mentioned earlier, where "python" was chosen as the guess, illustrates this. Starting to develop your game is never a terrible idea. With your editor, create the file wyrdl.py and fill it with the following details:
After reading the user's guess, you determine whether it matches the hidden word "python." You evaluate their intuition and inform them of its accuracy or inaccuracy.
You might not think there's much of a game here. And if you consider it a game, it's undoubtedly among the dullest and most frustrating. The secret word is the same every time. Thus there isn't much replay value. Additionally, the user cannot take action on the feedback because they cannot learn anything from being corrected.
You'll soon change your game to make it more entertaining to play. This subsection will be completed by addressing a minor usability problem. Consider the game that follows:
In this instance, you correctly deduced that the secret word is python. The game, however, informs you that's incorrect because it contrasts your guess with the uppercase string "PYTHON." This game's goal is to guess words, not to recognize capital or lowercase characters. How can two words, regardless of case, be compared?
Probably changing the guess explicitly to uppercase is the simplest solution. Afterwards, it makes no difference how the user enters the word:
Your addition of.upper() makes the user's guesses all uppercase. This modification immediately improves the game's usability. Python is now reported as correct even if you spell it with lowercase letters. Nevertheless, you only allow your users to make a good guess. You'll add more guesses to your game in the section after this one.
To prevent repetitive code, use loops.
When playing Wordle, you have up to six attempts to select the ideal word. To get the same outcome, you might duplicate the code you've previously created and include it six times in your game. That is unwise for several reasons. Most significantly, it will be difficult to maintain and inefficient.
Instead, you'll implement the recurring behaviour using loops. Python offers the for and while looping constructs. When performing definite iteration, you typically use for because you know ahead of time how many times you want to loop. While on the other hand, it is perfect for endless iteration when you are unsure how many times you will need to repeat a task.
In this situation, you will employ a for loop to ask the user to guess the word six times.:
You also count the number of guesses by iterating over a range, and you show the user that number
Once the user has discovered the solution, there is no purpose in allowing them to continue guessing. If the user selects the correct word, a break statement is used to exit the loop early. Break has the further benefit of eliminating the requirement for the explicit else. Your code only keeps running if the guess is accurate.
To make the game playable, it's time to incorporate some pertinent user feedback. In the following subsection, you'll see how to count the letters that users accurately guess.
Letters With Sets Check
The user has only been informed thus far as to whether or not they correctly guessed the term. You'll comment on the specific letters they correctly predicted to provide them with some cues they can utilize to figure out the hidden word. Each letter will be categorized into one of three groups by you:
How do you determine which letters go under various headings? Determine which letters are in the proper order, to begin with. Python's zip() method excels when comparing two sequences element by element. You are comparing the letters of two strings in this instance:
By comparing PYTHON and PROGRAM one letter at a time, you may identify the two incorrectly positioned characters in PROGRAM in this code sample. Despite the O being present in both terms, it is not reported because of its differing locations.
You must now gather the letters rather than print them. Python's comprehensions are strong building blocks that can be used to change one or more sequences into another. In this case, you'll apply a predetermined understanding to get the right letters:
Although it produces a set rather than a list, a set comprehension is similar to a list comprehension. Because it doesn't matter what order the correct letters are in, it works well in this circumstance.
Python has strong operations on sets, which is one of its benefits. To easily locate elements present in at least one set, both sets, or just one set, employ unions, intersections, and differences between the two sets.
You may use set intersection (&) to locate all the letters that appear in both strings, for instance, if you have two strings:
You can infer from the intersection that P and O are present in PYTHON and PROGRAM. The set difference can also be used to identify letters that appear in one set but not the other:
The letters N, Y, H, and T in PROGRAM are absent from PYTHON.
Sets can help you get better at your game now. You will, however, make one more adjustment before you begin the implementation. You currently have the secret word hard-coded into the if test. When categorizing letters, you'll utilize that term. Use the following constant to refer to it:
It is simpler to alter the secret word when WORD is introduced. The game will be more engaging if you provide a word list in the following part from which you can choose the word.
Now that you have learned about sets, you may compute and display the right, wrong, and misplaced characters. You should update your code to include the following:
You are currently only listing the categories and letters. For instance:
Although the information is present, understanding it is not always simple. However, the next step is adding some variation using a word list. Afterwards, you'll improve the game's user interface to improve the visual appeal and the player experience.
Step 2: Employ a word list
Even though the game's appearance is unchanged, you must attempt to identify a different word each time you play. You won't alter the functioning of your game in this phase. However, if you provide a word list, it'll be more entertaining and replayable. The secret word has been constant thus far. That will soon alter.
In this phase, you'll manually assemble a little word list and include it in your game. Creating a word list from any text will then be covered.
Manually Make a Word List
A plain text file containing your word list will have one phrase per line. This continues a long tradition on Unix systems where applications like spell checkers and similar ones use a file called words.
Create a new file called wordlist.txt and fill it with the following information to get started:
The words you looked into as possible guesses in the preceding phase have been included. Please feel free to add to the list. Please don't put too much effort into it; the word list will shortly be generated automatically.
You'll first consider how to read this list of words into your software before making a better list. The pathlib module of Python is excellent for handling various files and reading them into memory. Could you test it out?
The entire file is read as a single string using the. read text() method. The symbol n separates the words. These stand in for the file's newlines. Remove the final newline and divide the remaining lines to create a list of words:
You use the functions.strip() and. split() to turn the file into a list of words and delete any additional lines at the end of the file, respectively. To avoid worrying about lowercase and uppercase letters, you convert all words to uppercase.
Pick a Word at Random from a Word List
A robust random module is included with Python in the standard library. You can produce a variety of randomnesses for your projects. Apply random. Choice () to select one item at random from a series in this situation:
Running the same code may probably yield different results for you.
It's time to give your Wordle clone the word list feature. The following changes to your game:
At the top of your script, you've included the code to read a word list and select a random word from it. You've changed WORD to word because the secret word is no longer constant.
One minor negative is that if you incorrectly guess the word, your Wordle clone will never reveal the secret word it chose at random. By including the next at the end of your code, you can fix it.:
Despite being unusual, utilizing the otherwise clause with for can be extremely useful in some situations. The code included in the else block will be executed if the for loop doesn't terminate on its own, i.e. if the break ends the loop. In real life, that means that if every guess is different, the secret word is printed.
Many times play your game. When you don't know the actual term right away, it's already more difficult and enjoyable. Still, the game becomes repetitive due to the short word list. You'll then see how to make longer word lists.
Create a Word List from a Text
A word list is generally already installed on your computer, and you can also obtain word lists online. However, you might want to make your list for flexibility and control. This enables you to make specialized word lists that are themed and contain terms related to programming, place names, or other languages, for example.
A script you write will turn any text file into a properly formatted word list that you may use in your Wordle clone. Please create a new file called create wordlist.py and include the following text.
Explanation: Your script reads data from the command line using sys. argv. The first two command-line options are converted into paths and given the names in the path and out a path in lines 7 and 8. You must specify where the new word list file is and the path to an existing text file.
The following is an example of how you could use the script to turn your current copy of wyrdl.py into a word list:
The words are found when reading wyrdl.py and are then saved in wordlist.txt in the current directory. Remember that this will replace the wordlist.txt file that was manually created. Look at your updated word list:
Explanation: Several words will be familiar to you from your code. However, note that not all terms were included in the word list. Returning to create wordlist.py, notice in particular line 14. This line will filter your set comprehension by preventing words containing non-ASCII characters from being read. In actuality, it is limited to letters A through Z.
You should be aware that terms with more or fewer than five letters are not filtered out. Perhaps you should develop a Wordle variation that tests the user's knowledge of words with seven letters. While constructing the word list, you might do that. But you gain some flexibility by switching that job over to your wyrdl.py code. It enables the game's word length to be changed, as well as the use of conventional word lists.
The word list was sorted as well. The list can still be manually browsed without this, but it isn't necessarily necessary. To alter the sorting order, you specified the key on line 16.
With key=lambda word: (len(word), word), you sort words based on their length before sorting them based on their actual length. As a result, your word list begins with only one-letter words, then moves on to two-letter words, and so forth. Each group of identically long words is arranged alphabetically.
Now you can create your word list. Run you create wordlist.py script on any plain text file you can find. For example, you may download the whole works of Shakespeare to make an old-fashioned word list or a simplified version of Alice in Wonderland to make a list of easier words.
Explanation: As they were already filtered out by the if test, you also omit empty words. strip().
To make your code easier to work with in the long run, you must first rearrange it. The fact that the secret word is now randomly selected from a word list makes your game more engaging. You'll later work on improving the user experience with more logical feedback.
Step 3: Code Organization Using Functions
You've created a script for your game up to this point. It consists of a list of commands executed one at a time. These kinds of programmes don't scale well, even if they're ideal for getting started quickly and testing out a basic prototype of your game. You should organize your code into reusable functions as your programme becomes more sophisticated.
After completing this step, the game will still appear the same to your users. The underlying code, however, will be simpler to develop later.
In the following organization, the code appears as follows.:
Your game should now be playable after all these changes. Execute your programme to check that the game performs as it should.
Step 4: Game-Styling with Rich
If you've played Wordle online, you'll recognize the table of guesses and the coloured letters indicating whether a letter is correct, misplaced, or incorrect.
Get Familiar with the Rich Console Printer
You must install Rich, a third-party library, to utilize it. Create a virtual environment to install your project requirements before installing Rich. Choose your platform from the list below, then type the following commands:
Rich can be installed using pip after your virtual environment has been set up and launched.
You can test Rich after installation. Overriding the print() function is an easy approach to start utilizing Rich:
Rich employs a unique markup syntax that was modelled after bulletin board code. Rich will render the term Rich in bold with red font colour, even if it isn't visible in this code block. Style instructions are added in square brackets, as shown above with [bold red]. The style is in effect until you end it with [/].
You may utilize Rich to improve the visual appeal of your game by cleaning the screen in between guesses. You use a console for this. clear(). To your code, add the following function:
Using rule(), you may add a decorative horizontal rule to emphasize your printed text more. The screen will be cleared using the console. clear(). Then a headline will be printed at the top of the screen using the console. rule().
Maintain a record of earlier predictions and colour them
You'll use a list to keep track of all your educated estimates. The list can be started with "_____," five underscores, to serve as placeholders for potential guesses in the future. The placeholder will then be replaced as the user makes an educated guess.
Update main() as follows to begin:
Explanation: The presentation will then reflect the user's new predictions. All predictions will be printed to the screen using the new function, which uses Rich for attractive colour and layout. You will loop over the letters in each guess as you select the proper colour for each letter.
To make this easier, you switch from the old set-based reasoning to a new classification system for each letter. In the following code, display guesses() has taken the place of show guess():
You style the letter with a green background if it is accurate. You add a yellow background if the letter is misplaced?"that is, if the letter is incorrect but appears in the secret word. If a letter is incorrect, it is displayed against a grey backdrop, denoted by the hexadecimal value #666666. Finally, you dimly display the placeholder symbols.
The last guess is not updated in the database of guesses with the current implementation of the game over(). You did so by putting show guesses() before input ().
Step 5: Include validation and user comments
At this phase, you'll add tools to help users navigate your game if they take dramatic action.
The basic gameplay remains the same, but your programme is now more reliable and will help the user if they make any mistakes.
Congratulations! You've created a feature-rich Wordle clone that you can use and share with all your friends?"at least those familiar with using the terminal to execute Python programmes.