Today I Learned

20210701 Quizzler project - 5

돌맹이시터 2021. 7. 1. 19:32

 

먼저, 구조체 내부에서의 immutability에 대해 정리했다.

 

 

https://dmsitter.tistory.com/115

 

swift - immutability (구조체 안에서)

immutable -- let과 같이 불변 mutable -- var과 같이 가변적 struct Town { let name: String var citizens: [String] var resources: [String : Int] init(citizens: [String], name: String, resources: [Strin..

dmsitter.tistory.com

 

 

 

 

 

 

QuizBrain.swift의 struct 내부에 있는 두 함수(메소드)를 비교해보면,

 

getProgress()는 property의 값을 변화시키지 않지만

nextQuestion()은 property(questionNumber)의 값을 변화시킨다.

 

기본적으로 struct의 property는 self로, 내부에서 값을 변화시킬 수 없기 때문에

immutability에 대해서 정리했던 글에 작성해둔 것처럼

mutating으로 마킹해줘야 한다.

 

 

 

 

'mutating'만 붙여주면,

 

기존에 MVC design pattern을 사용하지 않았을 때와 동일하게 어플이 만들어진 것을 테스트해볼 수 있다.

 

 

 

 


 

 

Challenge )

 

왼쪽 상단에 User score가 출력되도록 만들어볼 것, 마지막 문제가 끝나면 점수는 0으로 초기화시킬 것

 

1. main.storyboard에서 label을 추가

2. IBOutlet 연결 - 'scoreLabel'

3. updateUI() 코드블럭에 

scoreLabel.text = "Score : \(quizBrain.getScore())" 코드 추가

 

이후

 

 

 

 

 

메소드 부분을 위와 같이 수정하여 어플을 완성했다.

 

 

 

 


 

 

Challenge )

 

3가지 선택지가 있는 quizzler 만들기

 

 

import Foundation

struct Question {
    let text : String
    let answer : [String]
    let correctAnswer : String
    
    init(q : String, a : [String], correctAnswer : String) {
        text = q
        answer = a
        self.correctAnswer = correctAnswer
    }
}

Question.swift

 

 


import Foundation

struct QuizBrain {
    let quiz = [
        Question(q: "Which is the largest organ in the human body?", a: ["Heart", "Skin", "Large Intestine"], correctAnswer: "Skin"),
        Question(q: "Five dollars is worth how many nickels?", a: ["25", "50", "100"], correctAnswer: "100"),
        Question(q: "What do the letters in the GMT time zone stand for?", a: ["Global Meridian Time", "Greenwich Mean Time", "General Median Time"], correctAnswer: "Greenwich Mean Time"),
        Question(q: "What is the French word for 'hat'?", a: ["Chapeau", "Écharpe", "Bonnet"], correctAnswer: "Chapeau"),
        Question(q: "In past times, what would a gentleman keep in his fob pocket?", a: ["Notebook", "Handkerchief", "Watch"], correctAnswer: "Watch"),
        Question(q: "How would one say goodbye in Spanish?", a: ["Au Revoir", "Adiós", "Salir"], correctAnswer: "Adiós"),
        Question(q: "Which of these colours is NOT featured in the logo for Google?", a: ["Green", "Orange", "Blue"], correctAnswer: "Orange"),
        Question(q: "What alcoholic drink is made from molasses?", a: ["Rum", "Whisky", "Gin"], correctAnswer: "Rum"),
        Question(q: "What type of animal was Harambe?", a: ["Panda", "Gorilla", "Crocodile"], correctAnswer: "Gorilla"),
        Question(q: "Where is Tasmania located?", a: ["Indonesia", "Australia", "Scotland"], correctAnswer: "Australia")
    ]
    
    var questionNumber = 0
    var quizScore = 0
    
    //아랫줄에서 answer은 external parameter, 함수 외부에서 사용할 수 있음
    //userAnswer는 internal parameter, 이 함수 안에서 사용할 수 있음
    //만약 external parameter name을 사용하지 않을거라면 '_'으로 대신하면 된다.
    //func checkAnswer(_ userAnswer: String)와 동일
    mutating func checkAnswer(correctAnswer userAnswer: String) -> Bool {
        if userAnswer == quiz[questionNumber].correctAnswer {
            //user got it right
            quizScore += 1
            return true
        } else {
            //user got it wrong
            return false
        }
    }
    
    func getQuestionText() -> String {
        return quiz[questionNumber].text
    }
    
    func getAnswerSheet(buttonNumber : Int) -> String{
        if buttonNumber == 0 {
            return quiz[questionNumber].answer[0]
        } else if buttonNumber == 1 {
            return quiz[questionNumber].answer[1]
        } else {
            return quiz[questionNumber].answer[2]
        }
        
    }
    
    func getProgress() -> Float {
        return Float(questionNumber + 1) / Float(quiz.count)
    }
    
    mutating func nextQuestion() {
        if questionNumber < quiz.count - 1 {
            questionNumber += 1
        } else {
            quizScore = 0
            questionNumber = 0
        }
    }
    
    func getScore() -> Int {
        return quizScore
    }
    
}

 

 

QuizBrain.swift

 

 

 

//
//  ViewController.swift
//  Quizzler-iOS13
//
//  Created by Angela Yu on 12/07/2019.
//  Copyright © 2019 The App Brewery. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var progressBar: UIProgressView!
    
    @IBOutlet weak var firstButton: UIButton!
    @IBOutlet weak var secondButton: UIButton!
    @IBOutlet weak var thirdButton: UIButton!
    @IBOutlet weak var scoreLabel: UILabel!
    
    var quizBrain = QuizBrain()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        updateUI()
    }
    
    @IBAction func answerButtonPressed(_ sender: UIButton) {
        
        let userAnswer = sender.currentTitle!
        //QuizBrain.swift에서 external parameter name을 _로 입력한 경우
        //quizBrain.checkAnswer(userAnswer) 아래와 동일

        let userGotItRight = quizBrain.checkAnswer(correctAnswer: userAnswer)
        //QuizBrain.swift에서 external parameter name을 answer로 입력한 경우
        
        
        if userGotItRight {
            // UIcolor == 미리 build되어 있는 color
            sender.backgroundColor = UIColor.green
        } else {
            sender.backgroundColor = UIColor.red
        }
        
        quizBrain.nextQuestion()
        
        Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
        
    }
    
    @objc func updateUI() {
        questionLabel.text = quizBrain.getQuestionText()
        firstButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 0), for: .normal)
        secondButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 1), for: .normal)
        thirdButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 2), for: .normal)
        progressBar.progress = quizBrain.getProgress()
        firstButton.backgroundColor = UIColor.clear
        secondButton.backgroundColor = UIColor.clear
        thirdButton.backgroundColor = UIColor.clear
        //questionNumber가 0부터 시작하기 때문에, 첫 Q일 때도 progressBar가 진행되도록 하기 위해 questionNumber + 1 사용함
        scoreLabel.text = "Score : \(quizBrain.getScore())"
    }
    
    
}

viewController.swift

 

 

 

완성!

'Today I Learned' 카테고리의 다른 글

20210711 Destiny project -2  (0) 2021.07.12
20210706 Destiny project -1  (0) 2021.07.06
20210628 Quizzler project - 4 (with MVC design pattern)  (0) 2021.06.29
20210627 Quizzler project -3  (0) 2021.06.27
20210623 Quizzler project -2  (0) 2021.06.24