Project 8: 7 Swifty Words – Part 3

by | March 20, 2019

Project 8: 7 Swifty Words – Part 3

Jeff Summers

March 20, 2019

Today marked the end of Project 8 in the 100 Days of Swift challenge. With each new project we are introduced to new concepts or ways to implement the concepts that we have previously been introduced to. This project was extremely taxing from a keyboarding perspective but oddly, I felt more comfortable at the end of this exercise than I had in previous ones.

Perhaps it is a false sense of confidence. That’s not to say I feel like I have a complete handle on what we did. It seems as if every time I learn something new in Swift it introduces 12 things that I didn’t know. There are times that this feels like taking a boat out on the lake and realizing it has a hole in the bottom. Every time I scoop a bucket of water out of the boat two buckets of water flow into the boat. The only question I keep asking myself is how long do I think I can tread water?

I find that I almost look forward to the challenges during the project wrap-up. I don’t know if that means that my confidence is building in being able to do things without following blindly to a tutorial or if I am just a glutton for punishment. Perhaps it is a little of both.

I was excited to see the challenges and even more excited that I actually had a plan of attack of how to accomplish them; yeah me! We had three challenges and I added one of my own for good measure.

The first challenge was to add an outline to the area where the word bits show to differentiate it from the rest of the screen. Paul Hudson gave us a hint that we had previously done something similar in Project 2 adding an outline to the country flags to differentiate the white on a flag from the white background.

buttonsView.layer.borderWidth = 1
buttonsView.layer.borderColor = colorLiteral(red: 0.5058823824, green: 0.3372549117, blue: 0.06666667014, alpha: 1)

This required two lines of code where we created the subView for the buttonsView. I could have simply used .black for the borderColor but I again used Color Literal to allow me to select and change the colors from a selectable palette.

The second challenge was to provide the user with an alert box telling them when they made a wrong choice after submitting a word. I added an else statement to the check to see if the word submitted was found in the answers.

if let solutionPosition = solutions.firstIndex(of: answerText) {
activatedButtons.removeAll()

var splitAnswers = answersLabel.text?.components(separatedBy: "\n")
splitAnswers?[solutionPosition] = answerText
answersLabel.text = splitAnswers?.joined(separator: "\n")

currentAnswer.text = ""
score += 1

if answersLabel.text?.contains("letters") == false {
var alertTitle = ""
var alertMessage = ""
var buttonTitle = ""

if level < maxLevel { alertTitle = "Well Done!" alertMessage = "Are you ready for the next level?" buttonTitle = "Let's Go!" } else { // Set background to balloons and hide fields view.backgroundColor = UIColor(patternImage: UIImage(named: "background.png")!) scoreLabel.isHidden = true cluesLabel.isHidden = true answersLabel.isHidden = true currentAnswer.isHidden = true submit.isHidden = true clear.isHidden = true // Reset level to 0 before calling levelUp level = 0 alertTitle = "Congratulations!" alertMessage = "You have beaten all the current levels!" buttonTitle = "Let's Play Again!" } let ac = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert) ac.addAction(UIAlertAction(title: buttonTitle, style: .default, handler: levelUp)) present(ac, animated: true) } } else { let ac = UIAlertController(title: "Incorrect", message: "Sorry, that guess is incorrect", preferredStyle: .alert) ac.addAction(UIAlertAction(title: "Try Again", style: .default, handler: wrongAnswer)) present(ac, animated: true) }
I needed to add a couple of functions to complete this. Well technically I had to add one but that would have made me copy code from another place so I refactored the clearTapped function to move that code to the resetAnswer function. I then called that function both in clearTapped and also in wrongAnswer.

func wrongAnswer(action: UIAlertAction) {
score -= 1
resetAnswer()
}

func resetAnswer() {
currentAnswer.text = ""

for btn in activatedButtons {
btn.isHidden = false
}

activatedButtons.removeAll()
}

The final challenge was to deduct a point from the score when the user entered an incorrect word. That part was relatively easy as it just required adding “score -= 1” in the wrongAnswer function. The problem was that by doing that, it messed up the logic for telling when a level was completed.

The original code would check if a decision remainder was 0 when score was divided by 7. This no longer works since the score could be less than 7 but all the words have been guessed. If you look at the code above, you will see how I did that.

I instead checked to see if answersLabel.text contained the word “letters”. It would return false if all the words had been guessed since we replaced the number of letters with the word guessed. At first, I was worried that this would break if we ever had a puzzle that contained the word “letters” but since Swift is case-sensitive that would not occur since our answer words are in uppercase and the hint text is in lowercase. Thank heavens for case sensitivity!

I added one additional challenge for myself. I felt like the game needed a “Restart” button that when clicked would reset the game back to the beginning. That required adding a new button called restart then adding the appropriate constraints to it. When pressed that button would call a function that resets the score, the level, clears all the in-progress word arrays, and loads a level.

@objc func restartTapped(_ sender: UIButton) {
// Reset score and level
score = 0
level = 1

// Reset the buttons and game
resetBoard()

loadLevel()
}

func resetBoard() {
solutions.removeAll(keepingCapacity: true)

for btn in letterButtons {
btn.isHidden = false
}

}

The resetBoard function is a refactoring to put that logic in one place that can be called whether a user goes to a new level or restarts the game.

In all, this has been a very educational project that has provided a lot of opportunity to implement what we have learned. Even that last self-induced challenge allowed me to go back and revisit the constraints we set programmatically to make the “Restart Game” button align with the score label but be left justified rather than right justified.

Share this Article

Posted by Jeff Summers

Author, technologist, and baseball aficionado specializing in information technology and developing new and creative ways to interact with the world around us. My goal is to extend the boundaries of what is possible and find ways to make the world a better place while having fun.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Stay Connected

Search

More Articles

Pace Layered Architecture Categorization

Change is inevitable. Today’s computing environments are constantly in flux from internal and external forces that put demands on the systems and necessitate changes to maintain its value stream. Technology currency is a constant struggle that organizations must...

TBM, Another Holy Grail?

Technology Business Management or TBM as a term was coined around 2012 although many of the concepts making up this framework have been around for almost as long as there has been IT. In its simplest form, TBM represents the integration of business, technology, and...

Visionary or Dreamer?

Thinking back over your life you’ve met and worked with countless personality types. You have been a part of teams that struggled to complete simple tasks and the work felt meaningless. Perhaps your goal in these times was to just trudge through the mud hoping the...

Archives