[Swift 1] Day 8 - Code Exercise Solution


#1
  1. What do you think of if/else statements?
  2. How is your first iPhone game?
  3. Why would you use Optionals?

Please share your code or answers with your classmates for the Day 8 Code Exercise and related Notebook Activity questions.

Day 8 Course Videos
Day 8 Code Exercise - Number Guessing Game


#2

lets have some fun :slight_smile:
played with conditions to say higher / lower but hot and cold too.
And as the message were so boring if we are several times in the same spot, add some random motivation string :slight_smile:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var resultTextField: UILabel!
    @IBOutlet weak var playerInputTextField: UITextField!
    
    var messages:[String: String] = [
        "welcome": "Lets play, guess my number",
        "cold":" you are cold, really cold",
        "hot":" but whoa, you're so hot",
        "higher":"Try higher",
        "lower": "Try lower",
        "win": "Yeahh you got me",
        "invalidnumber": "Nop, try with an integer"]
    
    var again = ["again", "...still", "no change!", "make an effort", "come on"]
    var lastResult:String = ""
    
    var numberToGuess:Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        startAGame()
        
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    // Helpers
    func getRandomIntNumber(range: Int) -> Int {
        
        return Int(arc4random_uniform(UInt32(range)))
    }
    
    func startAGame() {
        playerInputTextField.text = ""
        resultTextField.text = messages["welcome"]
        numberToGuess = getRandomIntNumber(1000)
    }
    
    //Buttons

    @IBAction func guestButtonActivated(sender: UIButton) {
        
        if let playerNumber = playerInputTextField.text.toInt() {
            
            if playerNumber < numberToGuess {

                resultTextField.text = messages["higher"]
                
                if abs(playerNumber - numberToGuess) < 50 {
                    
                    resultTextField.text! += messages["hot"]!
                    
                    
                } else if abs(playerNumber - numberToGuess) > 500 {
                    
                    resultTextField.text! += messages["cold"]!
                }
                
            } else if playerNumber > numberToGuess {
                
                resultTextField.text = messages["lower"]
                
                if abs(playerNumber - numberToGuess) < 50 {
                    
                    resultTextField.text! += messages["hot"]!
                    
                } else if abs(playerNumber - numberToGuess) > 500 {
                    
                    resultTextField.text! += messages["cold"]!
                }
                
            }
            
            if resultTextField.text == lastResult {
                
                resultTextField.text! += " \(again[getRandomIntNumber(again.count)])"
                
            } else {
                
                lastResult = resultTextField.text!
                
            }
            
            if playerNumber == numberToGuess {
                
                    resultTextField.text = messages["win"]
                    lastResult = ""
            }
            
            
        } else {
    
            resultTextField.text = messages["invalidnumber"]
            playerInputTextField.text = ""
        }
    }

    @IBAction func resetButtonActivated(sender: UIButton) {
        
        startAGame()
    }
}

The UI with constraints (the result line is set to 0 to allow multi line result as we could have looooong strings here :

Answers :

If / else :
they are major notion in the flow. Sometimes switch / case is more appropriate but only in some specific cases.
Optionals :
as the value may or may not be set, they are useful to catch exceptions ( as the textField.text.toInt() example in that code).
But sometimes we know for sure the value is set so we use the ! to force the unwrapped and not the ? like in the lastResult = resultTextField.text! in the code above.


Beginners Group
#3

Create a number guessing game using if/else statements.

UI

Code

Trivia: #pragma mark is a very nice way to document the code in Objective-C. I found this alternative in Swift. It helps on code organization.

Where would you use conditionals in your app?

When I need to execute different pieces of code based on certain conditions. That is, when I need to manage the app flow.

Find an example of a published app (App Store) that you uses an if/else statement.
On what screen do they use it?
What does it do?

My app uses a simple if / else to enable or disable the offline mode.

What are Optionals?

Optionals are a GREAT addition to the Swift language. From the docs (under “Optionals”):

You use optionals in situations where a value may be absent. An optional says:

There is a value, and it equals x*
or
There isn’t a value at all

So it’s a way do declare a variable that may or may not hold a value.

How do Optionals compare to Objective-C nil pointers?

Here’s where it shines. Still from the docs (under “Optionals”), I couldn’t put it in a better way:

The concept of optionals doesn’t exist in C or Objective-C. The nearest thing in Objective-C is the ability to return nil from a method that would otherwise return an object, with nil meaning “the absence of a valid object.” However, this only works for objects—it doesn’t work for structures, basic C types, or enumeration values. For these types, Objective-C methods typically return a special value (such as NSNotFound) to indicate the absence of a value. This approach assumes that the method’s caller knows there is a special value to test against and remembers to check for it. Swift’s optionals let you indicate the absence of a value for any type at all, without the need for special constants.

Finally:

Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.


#4

Hey there,

here’s the link to my solution on the code exercise. Made this very simple. :smile:

https://gist.github.com/thedan84/17ba47ff435f2d8dbcb9#file-random-number-challenge


#5

Here is my code

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var guessTheNumberLabel: UILabel!

@IBOutlet weak var responseLabel: UILabel!

@IBOutlet weak var guessTextField: UITextField!


var number: Int!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
    number = Int(arc4random_uniform(150)) + 1
    
    
    
    }

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
@IBAction func guessButtonPressed(sender: AnyObject) {
    
    var guess:Int = guessTextField.text.toInt()!
    
    if guess == number {
        responseLabel.text = "You lucky bastard.You won my game"
        
    } else if guess < number {
        responseLabel.text = " Number is greater then \(guess)"
    } else if guess > number {
        responseLabel.text = " Number is less then \(guess)"
    }
    


}


@IBAction func resetButtonPressed(sender: AnyObject) {
number = Int(arc4random_uniform(150)) + 1
    responseLabel.text = "Guess a number"
    guessTextField.text = "75"
}

}


#6

Hello everyone!
Here is my code: https://gist.github.com/eloisecamire/cd2ed113e53bc9ad2631

I tried giving more clues when player guess is closer to the number. Very simple but it has a little bit or variation.

I tried putting a background image with Bennie’s code this time. Much more easier than using the Image View but it’s making a pattern as suggested in the title, so it should be used with a tile image I think… but it still work with a iphone size image too.
Bennie’s code: view.backgroundColor = UIColor(patternImage: UIImage(named: “image.jpg”))


#7

i always love your ui design, so nice.


#8

Indeed. @Eloise, are you a wizard?!


#9

Ok, finally done with this.
This is doing a toll on my sleep :smile:

I didn’t want to make a button ( lazy lazy players )
So figured out the damn delegate method…
I did put some note in code, in case anyone ( besides me :slight_smile: ) needs them :smile:

I did add lives, so it only gives you 10 tries, then it will start over.
Also if you did win a small Star will show up :smile:

Sorry things might be made in a retarded way, but I think it works :smiley:
Here are some pics:

App is here:

https://drive.google.com/file/d/0B00fLVsdls5VU2lDV0FLeVpXX00/view?usp=sharing

Code is:

//
//  ViewController.swift
//  test_BG
//
//  Created by Razvigor Andreev on 10/14/14.
//  Copyright (c) 2014 Razvigor Andreev. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    
    
//   background View
    
    @IBOutlet weak var view2: UIView!
    
//    images
    
    
    @IBOutlet weak var star: UIImageView!
    
    
    
    
//  iVars
        var number: Int!
        var guessedNumber: Int!
        var lives = 10

//  Labels
    
    @IBOutlet weak var numberInputField: UITextField!
    @IBOutlet weak var message: UILabel!
    @IBOutlet weak var livesLabel: UILabel!
    
        override func viewDidLoad() {
        super.viewDidLoad()
            
            
     
//   Load on Start
            
            self.view2.backgroundColor = UIColor(patternImage: UIImage(named: "wood.jpg"))
            livesLabel.text = "Lives: \(lives)"
            message.text = ("Welcome! Try your luck !")
         
//   Random number generator
            
            number = Int(arc4random_uniform(100) + 1)
            println("\(number)")
            numberInputField.delegate = self
            
        
            

// Do any additional setup after loading the view, typically from a nib.
            
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    
//  Function to track if Enter has been pressed, using the delegate
    
    @IBAction func refreshPressed(sender: UIButton) {
        refresh()
    }
    
   
    
    func textFieldShouldReturn(textField: UITextField!) -> Bool {
    
        println("Return pressed")
        
        
        guessedNumber = numberInputField.text.toInt()
        println("\(guessedNumber)")
        if let customWord = guessedNumber {
            
            if customWord == number {
                message.text = ("You won!")
                star.hidden = false
                
            }
            if customWord < number && customWord >= 1 {
                message.text = ("Wrong! My number is higher ! :) ")
                lives = lives - 1
                checkAlive()
            }
            if customWord > number && customWord <= 100 {
                message.text = ("Wrong! My number is lower! :) ")
                lives = lives - 1
                checkAlive()
            }
            
            if customWord > 100 || customWord <= 0{
                
                message.text = ("Use only numbers between 1 and 100! Try again!")
            }
        
        }
        else {
            
            message.text = ("Please use only numbers between 1 and 100! Try again! :)")
            println("bad")
            
        }
    
    
    
 
    
        return true;
    }
    
    func checkAlive() {
        livesLabel.text = "Lives: \(lives)"
        if lives <= 0 {
            
            println("dead")
            message.text = "Game Over :/"
            refresh()
        }
       
        
    }
    
    
    
    func refresh() {
    
        star.hidden = true
    number = Int(arc4random_uniform(100) + 1)
    println("New Random Number is: \(number)")
    message.text = "New Game Started ! Good Luck ! "
        lives = 10
        checkAlive()
    }
    
    @IBAction func guessingTouched(sender: UITextField) {
        numberInputField.text = ""
    }

}

#10

1.- What do you think of if/else statements?
A: It is a good approach when we need to compare in order to take decisions.

2.- How is your first iPhone game?
A: Just starting working on…

3.- Why would you sue Optionals?
A: To handle nil and no nil values of a variable.

Here is my code for Guessing Number: https://gist.github.com/ariasfigueroa/5614715b606294266ef4


#11

added a “Guess” button to the “Number Pad” (google helped…):

private func addGuessButtonTo(textField: UITextField) {
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    let guessBarButton = UIBarButtonItem(title: "Guess", style: UIBarButtonItemStyle.Plain, target: self, action: "didGuessDone:")
    let keyboardToolbar = UIToolbar()
    keyboardToolbar.sizeToFit()
    keyboardToolbar.items = [flexBarButton, guessBarButton]
    textField.inputAccessoryView = keyboardToolbar
}

func didGuessDone(sender: AnyObject?) {
    guess()
}

the “guess()” function is just checking the user input

jvc


#12
  1. If else statements are very powerful way of taking your variables and crafting solutions to your problems that you are trying to solve.

  2. The first game is shown below. The code is in Github repository for guessing game
    Its ok as I am happy with it, The screen doesn’t go up to show the box being filled. I know we cover that later.
    The only issues are that if you put in non numbers it crashes but I used a number pad so it shoulnt be possible to do that.

I was very happy to learn how to use github to make different branches so I could work in my lunchbreak at work sometimes without taking my laptop home. I also have started to make my own code snippets in Xcode with things we are learning here.
I am so so slow!!

  1. Optionals are good to check if the format of the answer is correct e.g. an integer. I also used it to convert the string into an integer. 2 for 1 code.

Code:

//
//  ViewController.swift
//  Day 8 Number guessing game
//
//  Created by Sasha Akhavan-Zanjani on 07/03/2015.
//  Copyright (c) 2015 Sasha Akhavan-Zanjani. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    var numberGuessGiven = UInt()

    func UIColorFromRGB(rgbValue: UInt) -> UIColor {
        return UIColor(
            red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
            alpha: CGFloat(1.0)
        )
    }
    
//  Linkage
    
    @IBOutlet weak var numberEnterTextField: UITextField!

    @IBOutlet weak var guessesLeftTextLabel: UILabel!
    
    @IBOutlet weak var feedbackMessageLabel: UILabel!
    
    
//  Set up some variables
    var numberToGuess = Int()
    var guessesLeft = Int()
    var numberOfAttempts = Int()
    var gameOver = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        view.backgroundColor = UIColorFromRGB(0xf39c12)


        newGame()
        println("viewDidLoad")
    }
  
    
    //    Set up Random Number
    func generateRandomNumber (){
    
    numberToGuess = Int(arc4random_uniform(100)) + 1
        println("generateNumber")
        println("\(numberToGuess)")

    }
    
    @IBAction func GuessButton(sender: UIButton) {

        var numberGuessGiven = numberEnterTextField.text
        var number : Int? = numberGuessGiven.toInt()
        var numberDifference = numberToGuess - numberGuessGiven.toInt()!
        
        feedbackMessageLabel.text = "You guessed \(numberGuessGiven)"

        println("guessbutton")
        println("numberof attempts \(numberOfAttempts)")
        println("guesses left \(guessesLeft)")
        println("number \(number)")

//      check correct format given
        if let guess = numberEnterTextField.text.toInt() {
 
            ++numberOfAttempts
            guessesLeft = guessesLeft - 1
            
//          guessing game part
            if numberDifference == 0 && number <= 100 {
                feedbackMessageLabel.text = "Well done you are correct the number is \(numberGuessGiven)"
                guessesLeftTextLabel.text = "\(guessesLeft)"

            }   else if numberDifference <= 10  && number <= 100 {
                feedbackMessageLabel.text = "You are very close"
                guessesLeftTextLabel.text = "\(guessesLeft)"
            }
                else if numberDifference >= 10 && numberDifference < 30 && number <= 100 {
                feedbackMessageLabel.text = "You are getting closer"
                guessesLeftTextLabel.text = "\(guessesLeft)"
            }
                else if numberDifference >= 30 && numberDifference < 50 && number <= 100 {
                feedbackMessageLabel.text = "A bit better keep trying"
                guessesLeftTextLabel.text = "\(guessesLeft)"
            }
                else if number <= 100 {
                feedbackMessageLabel.text = "You are miles away"
                guessesLeftTextLabel.text = "\(guessesLeft)"
            }
                else if number >= 100 {
                feedbackMessageLabel.text = ("Please input a valid number!")

            }
        
            } else {
                feedbackMessageLabel.text = ("Please input a valid number!")
            }
        

        if guessesLeft <= 0  {
            gameOver = true
            feedbackMessageLabel.text = "You loose, the answer is \(numberToGuess) Want to try again? Press reset"
        }
    }
    
    
    //    resets the game ready to start
    func newGame(){
        guessesLeft = 10
        var numberOfAttempts = 0
        var gameOver = false
        //        feedbackMessageLabel.text = "Can you guess the number in 10 attempts?"
        guessesLeftTextLabel.text = "\(guessesLeft)"
        numberEnterTextField.text = ""
        generateRandomNumber()
        println("newgame")
        println("numberof attempts \(numberOfAttempts)")
        println("guesses left \(guessesLeft)")
        
    }
    @IBAction func resetButton(sender: UIButton) {
        newGame()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

#13

I used Conditionals to take the number guessed and give a reply based on what they had guessed. It is a way of assessing an input and giving a reply (action or whatever) in response with your requirement output.
Optionals gives a either a value or nil. So if I have an Int optional you can access is it an int if not then the answer is nil. Its great to see if the correct information has been input into the optional and use the nil to sort out that error. From the book “Swift also introduces optional types, which handle the absence of a value”.


#14

Great work @sashaz !

When you post code, try and remove extra new lines (returns) so that you can read all the code.

Also, after you paste the code, highlight it and press the </> button on the forum editing tools. That’ll indent everything so that your code displays correctly on the forum.

I’ve fixed it, so it’s a little easier to read.

It crashes because you force unwrap an optional value using the !

You need to make sure you check the value can be converted before you use it. That’s what you’ll learn throughout the course.

if let guess = numberGuessGiven.toInt() != nil {
    var numberDifference = numberToGuess - guess

       // do something with guess (unwrapped Int variable)

}

If you always check a value that can be nil (converting ADHD to numbers doesn’t work and will make it nil!), you won’t have crashes from user input (very important not to crash and make users unhappy).


#15

code

  • What do you think of if/else statements?

If conditions not too complicated, it’s ok to use if/else, this exercise maybe switch/case more match.

  • How is your first iPhone game?

Not too bad :slight_smile:

  • Why would you use Optionals?

To check that variable have valued or nil, so it can help me to avoid crash.


#16

Hi Paul and others,

I am really enjoying your sessions, never thought that I would actually be able to write an application (although I know I just started) :smile:

What do you think of if/else statements?
I know there are better options for decisions as used in this application like a enum and switches, but I suppose we see these later? For now the if statements do work but they make a bit of a mess of the code.

How is your first iPhone game?
COOL!!! :stuck_out_tongue_winking_eye: Never thought I might come this far and I really like the fact that you challenge us. I have read some books before about iOS programming but then you just type over what is shown to you and you do not learn to write your own code, this is much better!

Why would you use Optionals?
I think it is still difficult for me to make the decision but I think you have to use optionals when you are not sure that the variable might get a value during the applications lifetime? But then I just wonder, why not always use a variable as an optional?

My application checks if the user enters a numeric value, then it checks if this value is between 1 and 100. From there it will check if it is higher or lower then the number. And it shows a different message when you are:

  • more then 10 away
  • less than 10 but more then 3 away
  • less then 3 away

The user only has 10 guesses to guess the number and it will show game over when the user fails to do so and also removes the text field and “guess” button, only leaving the option to reset the game to the user.

When you click reset it will re-run viewDidLoad(), reset guessesLeft variable and show the textfield and guess button.

I will show my code below, thanks again for the great video’s Paul!!

//
// ViewController.swift
// NumberGuessingGame
//
// Created by Nico van der Linden on 01/06/15.
// Copyright © 2015 Noki-Online. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

// declaration of UI elements
@IBOutlet weak var guessedNumberTextField: UITextField!
@IBOutlet weak var guessesLeftLabel: UILabel!
@IBOutlet weak var systemMessageLabel: UILabel!
@IBOutlet weak var guessButton: UIButton!


// instance variable ivar)
var number: Int! // implicitely unwrapped value
var guessesLeft = 10

override func viewDidLoad() {
    super.viewDidLoad()
    guessButton.alpha = 1
    guessedNumberTextField.alpha = 1
    // Do any additional setup after loading the view, typically from a nib.
    
    // random number
    number = Int(arc4random_uniform(100) + 1)  // [0 - 99] + 1 = [1 -100]
    println("number: \(number)")
    
    // show initial amount of guesses left
    guessesLeftLabel.text = "\(guessesLeft)"
    
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func guessButtonPressed(sender: AnyObject) {
    
    // Check if a numeric entry was given
    if let number = guessedNumberTextField.text.toInt() {

        // check if number is between 1 and 100
        if number > 100 || number < 1 {
            systemMessageLabel.text = "Can't you read? between 1 and 100 I said!!"
        }
        else { // continue with game, valid input
            
            // check if enough guesses are left
            if guessesLeft > 1 {
                
                // number is LOWER
                if number > self.number && (number - self.number) >= 10 {
                    systemMessageLabel.text = "Not even close, much lower!"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                else if number > self.number && (number - self.number) < 10 && (number - self.number) > 3 {
                systemMessageLabel.text = "Number is lower"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                else if number > self.number && (number - self.number) <= 3 {
                    systemMessageLabel.text = "whooo, just a little bit lower"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                    
                // number is HIGHER
                else if number < self.number && (self.number - number) >= 10 {
                    systemMessageLabel.text = "Not even close, much higher!"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                else if number < self.number && (self.number - number) < 10  && (self.number - number) > 3 {
                    systemMessageLabel.text = "Number is higher"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                else if number < self.number && (self.number - number) <= 3 {
                    systemMessageLabel.text = "whooo, just a litle bit higher"
                    guessesLeft--
                    guessesLeftLabel.text = "\(guessesLeft)"
                }
                else {
                    systemMessageLabel.text = "congratulations, the number was: \(self.number)"
                }
                
            } //end of guesses check
            
            else { // not enough guesses left
                systemMessageLabel.text = "GAME OVER!!!"
                guessedNumberTextField.alpha=0
                guessButton.alpha = 0
                guessesLeft--
                guessesLeftLabel.text = "\(guessesLeft)"
            }
    
        } // end of valid number range input block
        
    } // end of valid number range
    else {
        systemMessageLabel.text = "Huh? That is a strange number??"
    }
    
} // end of guessButtonPressed action function

@IBAction func resetButtonPressed(sender: AnyObject) {
    viewDidLoad()
    guessesLeft = 10
    guessesLeftLabel.text = "\(guessesLeft)"
    systemMessageLabel.text = "Ok, let's try again"
    
}

} // end of view controller function