white and blue plastic blocks

100 Days of SwiftUI: Project 5 – WordScramble

We’re making a word game this time around in what Paul describes as “the last easy project”.

As we create our new word game we learn about more new app building blocks like List, onAppear and Bundle and get extra practice at the things we’ve already covered – which is definitely welcome.

Challenge

Another 3 challenges are set for us to improve and extend WordScramble.

Minimum length of guesses and disallowing the start word

For checking the minimum length of guess I add a checker method which returns true if the guess is 3 characters or more. Disallowing the start word is another method which compares the answer to the root word and returns true if they are not the same.

I add a call to each of these methods within addNewWord.

func addNewWord() {
  ...
  guard length(word: answer) else {
      wordError(title: "Word too short", message: "It needs to be at least 3 letters long!")
      return
  }
  
  guard isNotRootWord(word: answer) else {
      wordError(title: "Used root word", message: "You can't just use the root word!")
      return
  }
}

func length(word: String) -> Bool {
    word.count >= 3
}

func isNotRootWord(word: String) -> Bool {
    word != rootWord
}

Toolbar button to reset the game

I added a toolbar modifier to the List which calls startGame and I also added an extra line to the startGame method to reset the array. I don’t know if I missed Paul adding that during the project work but without it the list of words remained even when you changed the root word, which didn’t seem correct.

List {
...
}
.toolbar {
    Button("New word", action: startGame)
}

func startGame() {
    if let startWordsURL = Bundle.main.url(forResource: "start", withExtension: "txt") {
        if let startWords = try? String(contentsOf: startWordsURL) {
            let allWords = startWords.components(separatedBy: "\n")
            rootWord = allWords.randomElement() ?? "silkworm"
            usedWords.removeAll()
            return
        }
    }
    
    fatalError("Could not load start.txt from bundle.")
}

Add scoring

This was fairly easy to achieve by adding a new @State variable for tracking the score and then, within addNewWord, if answer is deemed correct its length is added to score. A simple Text view is used to display the current value of score. Lastly, we reset score to 0 when startGame is called.

I won’t post all the code here as it’s scattered around the file but you can see the changes in this commit.

Result

WordScramble on GitHub