How to Make a Game Like Wordle in SwiftUI: Part One
Learn how to create your own Wordle word-game clone in SwiftUI. Understand game logic as you build an onscreen keyboard and letter tile game board. By Bill Morefield.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Make a Game Like Wordle in SwiftUI: Part One
35 mins
- Getting Started
- Guessing a Letter
- Displaying a Guessed Letter
- Making a Guess
- Showing the Guess
- Building the Game Logic
- Connecting the Model and App
- Checking a Guess
- Checking For In-Position Letters
- Checking Remaining Letters
- Updating the Game Status
- Building the Gameboard View
- Starting a New Game
- Where to Go From Here
Though it’s been around since the fall of 2021, the web game Wordle became popular in early 2022. For a time, you could barely scroll through social media without seeing your friend’s daily puzzle results. The simple rules make the game easy to pick up, and the variety of English words keeps the game challenging.
In case you missed or chose to ignore the game, the rules of Wordle are simple. Each day, the game presents a random five-letter English word for you to guess. You get six guesses to find the word, and all guesses must be valid English words. After each guess, the game evaluates each letter. It then tells you whether each letter isn’t in the word at all, is in the word but incorrectly placed or is correctly placed in position. If you get the word right in six guesses, you win. If not, Wordle tells you the correct word.
In this tutorial, you’ll design and implement a version of Wordle in SwiftUI called Guess the Word.
Getting Started
Download the project by clicking Download Materials at the top or bottom of this page. Open the project in the starter folder in Xcode. Have a look at the views, models and resources, then build and run. You’ll interleave building the model for the game with views that show the player these elements. Time to get to work!
Guessing a Letter
The game consists of a game board and a keyboard used to enter letters. It also provides “Delete” and “Return” keys the player uses to confirm their guess. You can find the keyboard implemented in the KeyboardView.swift and KeyButtonView.swift files in the KeyboardViews group.
Each game shows the current and past guesses. After the user confirms a guess by tapping Enter, the game checks the guess against the target word. In this app, the Dictionary
class loads a dictionary of five-letter words and provides access to it for the program.
First, you’ll implement the basic element of the game, the guessed letter. Open GuessedLetter.swift in the Models group. From the description, you can see you need a way to reflect the status of each letter after the player submits a guess. Above the declaration of the GuessedLetter
struct, add the following code:
enum LetterStatus: String {
case unknown = "Unknown"
case notInWord = "Not in Word"
case notInPosition = "In Word, But Not This Position"
case inPosition = "Correct and In Position"
}
This enumeration contains a state for each possible outcome for a letter, including the initial unknown state before the player submits the guess. You provide a string for each state to describe the result.
Now, replace the contents of the GuessedLetter
struct with:
var id = UUID()
var letter: String
var status: LetterStatus = .unknown
This struct contains the letter the player guesses and the status of the guess, which defaults to unknown
.
Now that you have a struct to hold a guessed letter, you can update the view to show this letter, which you’ll do in the next section.
Displaying a Guessed Letter
Just like you started with the data model for the simplest element of the game, a GuessedLetter
, you’ll now work on its related view. Open GuessBoxView.swift in the GameBoardViews group. This view shows the letters that make up each guess. It will show the player the letter and its status in an overall guess. Add the following properties at the top of the struct:
var letter: GuessedLetter
var size: Double
var index: Int
These hold the GuessedLetter
to show along with a size for the view and the zero-based index of which guess you show. Now, replace the current placeholder view with:
Text(letter.letter)
.font(.title)
.frame(width: size, height: size)
.cornerRadius(size / 5.0)
Next, replace the preview with:
let guess = GuessedLetter(letter: "S", status: .inPosition)
GuessBoxView(letter: guess, size: 50, index: 1)
Activate the preview and see the result.
This letter is from a checked guess so it should provide feedback to the player on the status of this guess. You’ll do that by adding color to the tile. First, open GuessedLetter.swift under the Models group and add the following computed property to the GuessedLetter
struct:
var statusColor: Color {
switch status {
case .unknown:
return .primary
case .notInWord:
return .gray
case .notInPosition:
return .yellow
case .inPosition:
return .green
}
}
This method returns a Color
based on the current status. An unknown letter uses the current primary color. A letter not in the word appears in gray, a letter in the wrong position appears in yellow and a letter in the correct position appears in green. Now, go back to GuessBoxView.swift and replace the body of the view with:
Text(letter.letter)
.font(.title)
// 1
.foregroundColor(Color(UIColor.systemBackground))
// 2
.frame(width: size, height: size)
// 3
.background(letter.statusColor)
// 4
.cornerRadius(size / 5.0)
You show the letter for the guess in a Text
view with the title
font style. Then, you modify the Text
view by:
- Setting the foreground color to the
UIColor.systemBackground
. This makes the text the same color as the current background color of the view. - Setting the width and height of the view to the passed value.
- Setting the background color for the view to the color determined by the
statusColor
computed property you added in the previous step. - Adding a corner radius to give the letter tile a nice, rounded appearance.
After being checked, the result clearly shows the letter and status of the guessed letter.
With the view to show the letters of each guess implemented, you can now move on to the player’s guess. You’ll do that in the next section.
Making a Guess
Just like each letter has a status, the guess as a whole also has a status. Open Guess.swift in the Models group and add the following above the Guess
struct:
enum GuessStatus {
case pending
case complete
case invalidWord
}
Until the player submits the guess, it will be pending
. If the player doesn’t submit a valid word, it will be invalidWord
. Once a valid word is checked, the guess is complete
. Now, add the following code to the Guess
struct:
var word: [GuessedLetter] = []
var status: GuessStatus = .pending
var letters: String {
return word.reduce("") { partialResult, nextLetter in
partialResult.appending(nextLetter.letter)
}
}
A guess consists of an array of GuessedLetter
structs that hold the guessed letters. You also store a status that defaults to pending
. The letters
computed property provides access to the letters in the guess as a string. The property uses the reduce
method on the word
array to concatenate each letter into a single string and return this value.
With the Guess
implemented, you can now turn your attention to the view that displays it.