清一色の待ち当てクイズ作ってみた(swiftUI)

背景

待ちを判断する能力が欲しい。。前回Pythonを使って待ちの判定をしてもらうプログラムを作ってみたがそんなもの実践で使えるわけもなく。。

地道な努力あるのみ!ということでクイズアプリにして練習することにしました。

使用言語はswiftUIです。下に製品のコードほとんど全部載っけてます笑

完成品

完成品はこちらからダウンロードできます。

こんなものを作ってみました。

問題についてはPythonを使って自動生成してますのでこちらを見てみてください。

メンチン、待ち判定のプログラム作ってみたい(Python)

コード

メイン機能の実装全て載せてます笑

特に通信を行なっていないので問題ないはず、、、

バグ見つけたり悪い書き方してたりを発見してたらご一報のほどよろしくお願いします。

import UIKit

class ViewController: UIViewController, NextDelegate{
    let userDefaults = UserDefaults.standard
    var mode = "endless"

    override func viewDidLoad() {
        super.viewDidLoad()
        userDefaults.register(defaults: ["koukaonn": true])
        userDefaults.register(defaults: ["time": "--:--:--"])
        userDefaults.register(defaults: ["count": "0"])
        userDefaults.register(defaults: ["color": 0])
        userDefaults.register(defaults: ["buy" : 0])
        userDefaults.register(defaults: ["paisyu" : 0])
        
        let haikei_tmp: Int = userDefaults.object(forKey: "color") as! Int
        if haikei_tmp == 0 {
            view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        } else{
            view.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
        }
        
        
        // Do any additional setup after loading the view.
        
    }


    @IBAction func start(_ sender: Any) {
        mode = "timeattack"
        performSegue(withIdentifier: "next", sender: nil)
    }
    
    
    @IBAction func endless(_ sender: Any) {
        mode = "endless"
        performSegue(withIdentifier: "next", sender: nil)
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "next"{
            let nextVC = segue.destination as! NextViewController
            nextVC.delegate = self
            nextVC.mode = mode
        }
        
    }
}
import UIKit

protocol ResultDelegate {
    
}

class ResultViewController: UIViewController,ResultAnswerDelegate {
    
    @IBOutlet weak var correctStackView: UIStackView!
    var received_answer = [Bool]()
    var random_array = [Int]()
    var time = "00:00:00"
    var all_user_answers = [[Bool]]()
    var mode = ""
    var pai_list = [Int]()
    let userDefaults = UserDefaults.standard
    
    @IBOutlet weak var seikaisuLabel: UILabel!
    @IBOutlet weak var resultTime: UILabel!
    
    @IBOutlet var resultButton: [UIButton]!
    override func viewDidLoad() {
        super.viewDidLoad()
        var count = 0
        for i in 0...9{
            let maru_pic = UIImage(named: "maru")?.withRenderingMode(.alwaysOriginal)
            let batsu_pic = UIImage(named: "batsu")?.withRenderingMode(.alwaysOriginal)
            
            if received_answer[i] == true{
                resultButton[i].setImage(maru_pic, for: .normal)
                count += 1
            }
            else{
                resultButton[i].setImage(batsu_pic, for: .normal)
            }
            
                        
        }
        resultTime.text = String(time)
        seikaisuLabel.text = String(count) + "問/10問"
        
        if count == 10{
            userDefaults.set(time,forKey: "time")
        }
        
        let haikei_tmp: Int = userDefaults.object(forKey: "color") as! Int
        if haikei_tmp == 0 {
            view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        } else{
            view.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
        }

        // Do any additional setup after loading the view.
    }
    
    
    @IBAction func showAnswer(_ sender: UIButton) {
        performSegue(withIdentifier: "resultanswer", sender: sender.tag)
    }
    
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "resultanswer"{
            let resultAnswerVC = segue.destination as! ResultDetailViewController
            let tmp = sender as! Int
            
            resultAnswerVC.received_answer = received_answer
            resultAnswerVC.random_array = random_array
            resultAnswerVC.received_button_num = tmp
            resultAnswerVC.all_user_answers = all_user_answers
            resultAnswerVC.resulttime = time
            resultAnswerVC.mode = mode
            resultAnswerVC.pai = pai_list[tmp]
            resultAnswerVC.pai_list = pai_list
        }
    }

    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
import UIKit

protocol ResultAnswerDelegate {
    
}

class ResultDetailViewController: UIViewController ,NextDelegate{
    
    var received_answer = [Bool]()
    // random_array はrandom_array で出題した問題番号
    var random_array = [Int]()
    var received_button_num = 0
    let all_question = QuestionList()
    var resulttime = ""
    var all_user_answers = [[Bool]]()
    var mode = ""
    var user_answer = [Bool]()
    var correct_answer = [Bool]()
    var count = 0
    var pai = 0
    var pai_list = [Int]()
    let userDefaults = UserDefaults.standard

    @IBOutlet weak var back_b: UIButton!
    @IBOutlet weak var next_b: UIButton!
    @IBOutlet var questionImage: [UIImageView]!
    @IBOutlet var correctAnswer: [UIImageView]!
    @IBOutlet var yourAnswer: [UIImageView]!
    @IBOutlet weak var seikaiImage: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var show_num = 0
        
        var question_image_list = ["1"]
        var answer_image_list = [false]
        if mode == "timeattack"{
            next_b.isHidden = true
            seikaiImage.isHidden = true
            
            show_num = random_array[received_button_num]
            user_answer = all_user_answers[received_button_num]
            
            question_image_list = all_question.list[show_num].question
            answer_image_list = all_question.list[show_num].answer
        } else if mode == "endless"{
            back_b.isHidden = true
            show_num = random_array[count]
            question_image_list = all_question.list[show_num].question
            answer_image_list = all_question.list[show_num].answer
            if user_answer == correct_answer{
                seikaiImage.image = UIImage(named: "maru")
            } else {
                seikaiImage.image = UIImage(named: "batsu")
            }
        
        }
        
        if userDefaults.object(forKey: "color") as! Int == 0 {
            view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        } else if userDefaults.object(forKey: "color") as! Int == 1{
            view.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
        }
        
        
        for i in 0...12{
            
            var image_name = String(question_image_list[i])
            if pai == 1{
                image_name = String(question_image_list[i])+"_sou"
            } else if pai == 2{
                image_name = String(question_image_list[i])+"_man"
            }else{
                image_name = String(question_image_list[i])
            }
            questionImage[i].image = UIImage(named: image_name)
        }
            
        
        
        
        for i in 0...8{
            if answer_image_list[i] == false{
                let image_name = String(i+1)
                var tmp = UIImage(named: image_name)
                if pai == 1{
                    tmp = UIImage(named:  image_name + "_sou")
                    
                    
                    
                } else if pai == 2{
                    tmp = UIImage(named:  image_name + "_man")
                    
                } else {
                    tmp = UIImage(named: image_name)
                    
                }
                correctAnswer[i].image = tmp
            }else {
                let image_name_kurai = String(i+1)
                var tmp_kurai = UIImage(named: image_name_kurai)
                if pai == 1{
                    tmp_kurai = UIImage(named:  image_name_kurai + "_sou"+"_kurai")
                    
                    
                    
                } else if pai == 2{
                    tmp_kurai = UIImage(named:  image_name_kurai + "_man"+"_kurai")
                    
                } else {
                    tmp_kurai = UIImage(named: image_name_kurai + "_kurai")
                    
                }
                correctAnswer[i].image = tmp_kurai
            }
        }
        
        for i in 0...8{
            
            if user_answer[i] == false{
                let image_name = String(i+1)
                var tmp = UIImage(named: image_name)
                if pai == 1{
                    tmp = UIImage(named:  image_name + "_sou")
                    
                    
                    
                } else if pai == 2{
                    tmp = UIImage(named:  image_name + "_man")
                    
                } else {
                    tmp = UIImage(named: image_name)
                    
                }
                yourAnswer[i].image = tmp
            }else {
                let image_name_kurai = String(i+1)
                var tmp_kurai = UIImage(named: image_name_kurai)
                if pai == 1{
                    tmp_kurai = UIImage(named:  image_name_kurai + "_sou"+"_kurai")
                    
                    
                    
                } else if pai == 2{
                    tmp_kurai = UIImage(named:  image_name_kurai + "_man"+"_kurai")
                    
                } else {
                    tmp_kurai = UIImage(named: image_name_kurai + "_kurai")
                    
                }
                yourAnswer[i].image = tmp_kurai
            }
            
        }
        
            

        // Do any additional setup after loading the view.
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "back"{
            let resultVC = segue.destination as! ResultViewController
            
            resultVC.received_answer = received_answer
            resultVC.random_array = random_array
            resultVC.all_user_answers = all_user_answers
            resultVC.time = resulttime
            resultVC.mode = mode
            resultVC.pai_list = pai_list
        } else if segue.identifier == "next"{
            let nextVC = segue.destination as! NextViewController
            nextVC.random_array = random_array
            nextVC.count = count
            nextVC.mode = mode
            
        }
    }
    
    @IBAction func backButton(_ sender: Any) {
        performSegue(withIdentifier: "back", sender: nil)
    }
    
    @IBAction func nextButton(_ sender: Any) {
        count += 1
        performSegue(withIdentifier: "next", sender: nil)
    }
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
import UIKit
import AVFoundation
var player:AVAudioPlayer!

protocol NextDelegate {
    
}

class NextViewController: UIViewController,ResultDelegate,ResultAnswerDelegate {
    
    var delegate:NextDelegate?
    
    var mode = ""
    var pai = 0
    var pai_list = [Int]()
    let userDefaults = UserDefaults.standard
    @IBOutlet weak var question_count: UILabel!
    @IBOutlet weak var timerMinute: UILabel!
    @IBOutlet weak var timerSecond: UILabel!
    @IBOutlet weak var timerMSec: UILabel!
    @IBOutlet var answerButton: [UIButton]!
    @IBOutlet var questionImageView: [UIImageView]!
    
    var correct_answer = [Bool]()
    var count = 0
    var random_array = [Int]()
    var question_num = 0
    var question_image_list = [String]()
    var user_answer = [Bool]()
    var user_correct = [Bool]()
    var all_user_answers = [[Bool]]()
    weak var timer: Timer!
    var startTime = Date()
    
    let maru_path = Bundle.main.url(forResource: "maruSound", withExtension:"mp3")!
    let batsu_path = Bundle.main.url(forResource: "batsuSound", withExtension:"mp3")!
    

    
    let all_question = QuestionList()
    override func viewDidLoad() {
        super.viewDidLoad()
        // 問題をシャッフルする。インデックスが入ってる。
        random_array = [Int](0...all_question.list.count-1)
        random_array = random_array.shuffled()
        // 次の問題
        nextQuestion()
        if timer != nil{
                    // timerが起動中なら一旦破棄する
                    timer.invalidate()
                }
        startTimer()
        if userDefaults.object(forKey: "color") as! Int == 0 {
            view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
        } else if userDefaults.object(forKey: "color") as! Int == 1{
            view.backgroundColor = #colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1)
        }
        
        

        // Do any additional setup after loading the view.
    }
    
    override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(true)
            timer.invalidate()
        }
    
    // ここからの機能はボタンごとに押した時の動作を記述
    // 基本的には選択の状態のみを保持
    @IBAction func onepai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }

     @IBAction func twopai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
     }

    @IBAction func threepai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    @IBAction func fourpai(_ sender: UIButton) {
        sender.switchAction(onAction: {
        }) {
                }
    }
    
    
    @IBAction func fivepai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    
    @IBAction func sixpai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    
    @IBAction func sevenpai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    @IBAction func eightpai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    
    @IBAction func ninepai(_ sender: UIButton) {
        sender.switchAction(onAction: {
                }) {
                }
    }
    
    func nextQuestion(){
        pai = userDefaults.object(forKey: "paisyu") as! Int
        if pai == 3{
            pai = Int.random(in: 0..<3)
        }
        pai_list.append(pai)
        if mode == "timeattack"{
            if count > 9{
                timer.invalidate()
                performSegue(withIdentifier: "result", sender: nil)
                
            }else{
                for i in answerButton{
                    
                    if pai == 1{
                        
                        let tmp = UIImage(named:  String(i.tag) + "_sou")
                        
                        let tmp_kurai = UIImage(named: String(i.tag) + "_sou" + "_kurai")
                        i.setImage(tmp, for: .normal)
                        i.setImage(tmp_kurai, for: .selected)
                    } else if pai == 2{
                        let tmp = UIImage(named:  String(i.tag) + "_man")
                        
                        let tmp_kurai = UIImage(named: String(i.tag) + "_man" + "_kurai")
                        i.setImage(tmp, for: .normal)
                        i.setImage(tmp_kurai, for: .selected)
                    } else {
                        let tmp = UIImage(named: String(i.tag))
                        
                        let tmp_kurai = UIImage(named: String(i.tag) + "_kurai")
                        i.setImage(tmp, for: .normal)
                        i.setImage(tmp_kurai, for: .selected)
                    }
                    i.isSelected = true
                }

                question_num = random_array[count]
                question_image_list = all_question.list[question_num].question
                for i in 0...12{
                    var image_name = String(question_image_list[i])
                    if pai == 1{
                        image_name = String(question_image_list[i])+"_sou"
                    } else if pai == 2{
                        image_name = String(question_image_list[i])+"_man"
                    }else{
                        image_name = String(question_image_list[i])
                    }
                    
                    questionImageView[i].image = UIImage(named: image_name)
                        }
                correct_answer = all_question.list[question_num].answer
                count += 1
                user_answer = []
                question_count.text = String(count) + "問/10問"
            }
            
        } else if mode == "endless"{
            for i in answerButton{
                if pai == 1{
                    
                    let tmp = UIImage(named:  String(i.tag) + "_sou")
                    
                    let tmp_kurai = UIImage(named: String(i.tag) + "_sou" + "_kurai")
                    i.setImage(tmp, for: .normal)
                    i.setImage(tmp_kurai, for: .selected)
                } else if pai == 2{
                    let tmp = UIImage(named:  String(i.tag) + "_man")
                    
                    let tmp_kurai = UIImage(named: String(i.tag) + "_man" + "_kurai")
                    i.setImage(tmp, for: .normal)
                    i.setImage(tmp_kurai, for: .selected)
                }else {
                    let tmp = UIImage(named: String(i.tag))
                    
                    let tmp_kurai = UIImage(named: String(i.tag) + "_kurai")
                    i.setImage(tmp, for: .normal)
                    i.setImage(tmp_kurai, for: .selected)
                }
                i.isSelected = true
            }
            question_num = random_array[count]
            question_image_list = all_question.list[question_num].question
            for i in 0...12{
                var image_name = String(question_image_list[i])
                if pai == 1{
                    image_name = String(question_image_list[i])+"_sou"
                } else if pai == 2{
                    image_name = String(question_image_list[i])+"_man"
                }else{
                    image_name = String(question_image_list[i])
                }
                
                questionImageView[i].image = UIImage(named: image_name)
                    }
            correct_answer = all_question.list[question_num].answer
            question_count.text = String(count+1) + "問目"
            timerMinute.isHidden = true
            timerSecond.isHidden = true
            timerMSec.isHidden = true
        }
        
        
    }
    
    
    @IBAction func answer(_ sender: Any) {
        for i in answerButton{
            user_answer.append(i.isSelected)
        }
        
        if mode == "timeattack"{
            
            all_user_answers.append(user_answer)
            
            
            if user_answer == correct_answer{
                let url = maru_path
                
                if userDefaults.object(forKey: "koukaonn") as! Bool{
                    do {
                        player = try AVAudioPlayer(contentsOf: url)
                        player?.play()
                    } catch {
                        // couldn't load file :(
                    }
                }
                user_correct.append(true)
                let tmp: String = userDefaults.object(forKey: "count") as! String
                userDefaults.setValue(String(Int(tmp)!+1 ), forKey: "count")
                nextQuestion()
                
            }else{
                let url = batsu_path
                if userDefaults.object(forKey: "koukaonn") as! Bool{
                    do {
                        player = try AVAudioPlayer(contentsOf: url)
                        player?.play()
                    } catch {
                        // couldn't load file :(
                    }
                }
                user_correct.append(false)
                nextQuestion()
            }
        }else if mode == "endless"{
            if user_answer == correct_answer{
                let url = maru_path
                if userDefaults.object(forKey: "koukaonn") as! Bool{
                    do {
                        player = try AVAudioPlayer(contentsOf: url)
                        player?.play()
                    } catch {
                        // couldn't load file :(
                    }
                }
                
                let tmp: String = userDefaults.object(forKey: "count") as! String
                userDefaults.setValue(String(Int(tmp)!+1 ), forKey: "count")
                performSegue(withIdentifier: "resultanswer", sender: nil)
                
            }else{
                let url = batsu_path
                if userDefaults.object(forKey: "koukaonn") as! Bool{
                    do {
                        player = try AVAudioPlayer(contentsOf: url)
                        player?.play()
                    } catch {
                        // couldn't load file :(
                    }
                }
                performSegue(withIdentifier: "resultanswer", sender: nil)

            }
            
        }
        
        
        


    }
    
    func startTimer() {
            timer = Timer.scheduledTimer(
                timeInterval: 0.01,
                target: self,
                selector: #selector(self.timerCounter),
                userInfo: nil,
                repeats: true)
    }
    
    
    
    @objc func timerCounter() {
            // タイマー開始からのインターバル時間
            let currentTime = Date().timeIntervalSince(startTime)
            
            // fmod() 余りを計算
            let minute = (Int)(fmod((currentTime/60), 60))
            // currentTime/60 の余り
            let second = (Int)(fmod(currentTime, 60))
            // floor 切り捨て、小数点以下を取り出して *100
            let msec = (Int)((currentTime - floor(currentTime))*100)
            
            // %02d: 2桁表示、0で埋める
            let sMinute = String(format:"%02d", minute)
            let sSecond = String(format:"%02d", second)
            let sMsec = String(format:"%02d", msec)
            
            timerMinute.text = sMinute
            timerSecond.text = sSecond
            timerMSec.text = sMsec
            
        }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "result"{
            let resultVC = segue.destination as! ResultViewController
            
            resultVC.received_answer = user_correct
            resultVC.random_array = random_array
            resultVC.time = String(timerMinute.text!) + ":" +  String(timerSecond.text!) + ":" + String(timerMSec.text!)
            resultVC.all_user_answers = all_user_answers
            resultVC.mode = mode
            resultVC.pai_list = pai_list
            
        } else if segue.identifier == "resultanswer"{
            let resultAnswerVC = segue.destination as! ResultDetailViewController
            resultAnswerVC.mode = mode
            resultAnswerVC.user_answer = user_answer
            resultAnswerVC.correct_answer = correct_answer
            resultAnswerVC.count = count
            resultAnswerVC.random_array = random_array
            resultAnswerVC.pai = pai
            
            
        }
    }
    
    
}

extension UIButton {

    func switchAction(onAction: @escaping ()->Void, offAction: @escaping ()->Void) {

        //選択状態を反転
        self.isSelected = !self.isSelected

        switch self.isSelected {
        case true:
            //ONにする時に走らせたい処理
            onAction()
        case false:
            //OFFにする時に走らせたい処理
            offAction()
        }

    }
}

ここまで長々と載せていますが意味がわからないですね、、

全部は難しいですが、苦労したところなどを解説していきたいと思います。

コメント

タイトルとURLをコピーしました