如何快速进行多个问题测验,以便问题不会重演?

问题描述 投票:2回答:3

我对编程没有任何经验。我已经这样做了几个月看youtube视频。如果有人能帮助我,我将非常感激。当我使用模拟器运行代码时,它会在下一个新问题出现之前重复几次问题。我希望它能够运行,所以它提出了一个问题,而不是一遍又一遍地重复相同的问题。下面请找代码。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var QuestionLabel: UILabel!

    @IBOutlet weak var Button1: UIButton!

    @IBOutlet weak var Button2: UIButton!

    @IBOutlet weak var Button3: UIButton!

    @IBOutlet weak var Button4: UIButton!

    @IBOutlet weak var Next: UIButton!

    @IBOutlet weak var LabelEnd: UILabel!
    var CorrectAnswer = String()


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

    func RamdomQuestions () {
        var RandomNumber = arc4random() % 4
        RandomNumber += 1

        switch (RandomNumber) {

        case 1:
            QuestionLabel.text = "Hola familia, Cual es mi nombre? "
            Button1.setTitle ("Cesar", forState: UIControlState.Normal)
            Button2.setTitle ("Karlos", forState: UIControlState.Normal)
            Button3.setTitle ("William", forState: UIControlState.Normal)
            Button4.setTitle ("Chiqui", forState: UIControlState.Normal)
            CorrectAnswer = "2"

            break
        case 2:
            QuestionLabel.text = "Hola famili, cual es mi apellido? "
            Button1.setTitle ("Perez", forState: UIControlState.Normal)
            Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
            Button3.setTitle ("Garcia", forState: UIControlState.Normal)
            Button4.setTitle ("Sanchez", forState: UIControlState.Normal)
            CorrectAnswer = "1"

            break
        case 3:
            QuestionLabel.text = "Quien hace la lachona mas rica? "
            Button1.setTitle ("Willy", forState: UIControlState.Normal)
            Button2.setTitle ("Mario", forState: UIControlState.Normal)
            Button3.setTitle ("Karlos", forState: UIControlState.Normal)
            Button4.setTitle ("Juan David", forState: UIControlState.Normal)
            CorrectAnswer = "1"

            break
        case 4:
            QuestionLabel.text = "Quien hace las tartas mas lindas"
            Button1.setTitle ("Jili", forState: UIControlState.Normal)
            Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
            Button3.setTitle ("Garcia", forState: UIControlState.Normal)
            Button4.setTitle ("Leidy y Liz", forState: UIControlState.Normal)
            CorrectAnswer = "4"

            break

        default:
            break
        }
    }

    func Hide (){
        LabelEnd.hidden = true
        Next.hidden = true
    }

    func UnHide () {
        LabelEnd.hidden = false
        Next.hidden = false
    }

    @IBAction func Button1Action(sender: AnyObject) {
        UnHide()
        if (CorrectAnswer == "1") {
            LabelEnd.text = "Correcto"
        }
        else{
            LabelEnd.text = "Falso"
        }
    }

    func Button2Action(sender: AnyObject) {
        UnHide()
        if (CorrectAnswer == "2") {
            LabelEnd.text = "Correcto"

        }
        else{
            LabelEnd.text = "Falso"
        }
    }

    func Button3Action(sender: AnyObject) {
        UnHide()
        if (CorrectAnswer == "3") {
            LabelEnd.text = "Correcto"
        }
        else{
            LabelEnd.text = "Falso"
        }
    }

    func Button4Action(sender: AnyObject) {
        UnHide()
        if (CorrectAnswer == "4") {
            LabelEnd.text = "Correcto"
        }
        else{
            LabelEnd.text = "Falso"
        }
    }

    @IBAction func Next(sender: AnyObject) {
        RamdomQuestions()
    }
}
ios swift random arc4random
3个回答
0
投票

对此的典型解决方案是将一系列问题(或索引到您的模型中),然后将此数组洗牌,使其随机。然后你可以遍历这个改组的问题,它们会以很大程度上随机的方式出现,但你不必担心它们会再次出现。

在Swift 4.2中,您将使用内置的shuffleshuffled方法来重新排列阵列。


在4.2之前的Swift版本中,您必须自己对阵列进行洗牌。注意,生成随机数时,不应将arc4random%运算符一起使用。这引入了modulo bias。相反,使用arc4random_uniform,它在一系列值内生成均匀分布的随机数。并且对阵列进行改组,你应该使用Fisher-Yates算法,它可以消除由幼稚改组算法引入的一些微妙偏差。有关一般信息,请参阅Fisher-Yates article in Wikipedia。有关特定的Swift实现,请参阅How do I shuffle an array in Swift?。无论如何,算法看起来像:

extension MutableCollection {

    /// Shuffle the elements of `self` in-place.

    mutating func shuffle() {
        if count < 2 { return }    // empty and single-element collections don't shuffle

        for i in 0 ..< count - 1 {
            let j = Int(arc4random_uniform(UInt32(count - i)))
            if j != 0 {
                let current = index(startIndex, offsetBy: i)
                let swapped = index(current, offsetBy: j)
                swapAt(current, swapped)
            }
        }
    }

    /// Return shuffled collection the elements of `self`.

    func shuffled() -> Self {
        var results = self
        results.shuffle()
        return results
    }

}

然后您可以像这样使用它:

var questionIndexes = Array(0 ..< questions.count)  // builds an array [0, 1, 2, ... n-1], where _n_ is the number of questions
questionIndexes.shuffle()                           // shuffle that list

最终得到一个数字0到n-1的数组,这些数组被混洗(即以随机顺序出现,但没有数字出现多次)。你现在可以遍历这个questionIndexes数组,每个问题只会被问过一次,但它们会以随机顺序呈现。


几个不相关的观察:

  1. 您可能希望采用Cocoa命名约定,即方法和属性名称应始终以小写字母开头。只有数据类型(例如类或结构)和枚举以大写字母开头。
  2. 在Swift中执行switch语句时,您不需要break。 Swift并没有像Objective-C那样失败。当我处理下面的第5点时,事实证明我最终完全分解了switch语句,但仅仅为了将来的参考,你不需要在Swift中的每个break结束时使用case,就像在C语言中那样Objective-C等编程语言。事实上,如果你想要一个Swift case语句落到下一个语句,就像在Objective-C中一样,你必须使用fallthrough关键字。
  3. 您可能不应该将correctAnswer初始化为String()。只需将其声明为可选(如果需要,可以隐式解包)。
  4. 更好的是,correctAnswer应该是Int而不是String。我还使用从零开始的值,以便我可以轻松查找该值以确认是否按下了右键。
  5. 这是一个更高级的主题,但我建议从“控制器”(从模型中获取信息并更新视图的代码)中分离“模型”(即有关问题文本,潜在答案和正确答案的数据)。 。这是我们在应用程序中使用的model-view-controller范例的一部分。它使您的应用程序在将来更易于维护(例如,您可以添加更多问题,更改问题等,但不必触摸视图控制器中的代码)。它还能够实现更灵活的模式(例如,问题和答案可以由远程Web服务提供或存储在数据库中)。 例如,您可能有一个类型可以捕获问题,它的潜在答案,并确定哪个是正确的答案。 struct Question { let question: String let answers: [String] let correctAnswer: Int } 然后,您的模型可能包含一组Question对象: var questions: [Question] = [ Question( question: "Hola familia, Cual es mi nombre?", answers: ["Cesar", "Karlos", "William", "Chiqui"], correctAnswer: 1), Question( question: "Hola famili, cual es mi apellido?", answers: ["Perez", "Carvajal", "Garcia", "Sanchez"], correctAnswer: 0), Question( question: "Quien hace la lachona mas rica?", answers: ["Willy", "Mario", "Karlos", "Juan David"], correctAnswer: 2), Question( question: "Quien hace las tartas mas lindas?", answers: ["Jili", "Carvajal", "Garcia", "Leidy y Liz"], correctAnswer: 3) ] 请注意,原谅我在这些问题中根据您的问题中提出的问题更改了“正确答案”。我只是想说明我们正在处理从03(不是14)的数字。

将所有内容整合在一起,您可能会看到如下所示的实现:

import UIKit

struct Question {
    let question: String
    let answers: [String]
    let correctAnswer: Int
}

class ViewController: UIViewController {

    @IBOutlet weak var questionLabel: UILabel!

    @IBOutlet weak var button1: UIButton!
    @IBOutlet weak var button2: UIButton!
    @IBOutlet weak var button3: UIButton!
    @IBOutlet weak var button4: UIButton!

    lazy var buttons: [UIButton] = { return [self.button1, self.button2, self.button3, self.button4] }()

    @IBOutlet weak var nextButton: UIButton!

    @IBOutlet weak var endLabel: UILabel!

    var questions: [Question] = [
        Question(
            question: "Hola familia, Cual es mi nombre?",
            answers: ["Cesar", "Karlos", "William", "Chiqui"],
            correctAnswer: 1),
        Question(
            question: "Hola famili, cual es mi apellido?",
            answers: ["Perez", "Carvajal", "Garcia", "Sanchez"],
            correctAnswer: 0),
        Question(
            question: "Quien hace la lachona mas rica?",
            answers: ["Willy", "Mario", "Karlos", "Juan David"],
            correctAnswer: 2),
        Question(
            question: "Quien hace las tartas mas lindas?",
            answers: ["Jili", "Carvajal", "Garcia", "Leidy y Liz"],
            correctAnswer: 3)
    ]

    var questionIndexes: [Int]!
    var currentQuestionIndex = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        questionIndexes = Array(0 ..< questions.count)  // builds an array [0, 1, 2, ... n]
        questionIndexes.shuffle()                       // randomizes that list

        updateLabelsAndButtonsForIndex(0)
    }

    func updateLabelsAndButtonsForIndex(questionIndex: Int) {
        // if we're done, show message in `endLabel` and hide `nextButton`

        guard questionIndex < questions.count else {
            endLabel.hidden = false
            endLabel.text = "All done!"
            nextButton.hidden = true
            return
        }

        // update our property

        currentQuestionIndex = questionIndex

        // hide end label and next button

        hideEndLabelAndNextButton()

        // identify which question we're presenting

        let questionObject = questions[questionIndexes[questionIndex]]

        // update question label and answer buttons accordingly

        questionLabel.text = questionObject.question
        for (answerIndex, button) in buttons.enumerate() {
            button.setTitle(questionObject.answers[answerIndex], forState: .Normal)
        }
    }

    func hideEndLabelAndNextButton() {
        endLabel.hidden = true
        nextButton.hidden = true
    }

    func unhideEndLabelAndNextButton() {
        endLabel.hidden = false
        nextButton.hidden = false
    }

    // note, because I created that array of `buttons`, I now don't need
    // to have four `@IBAction` methods, one for each answer button, but 
    // rather I can look up the index for the button in my `buttons` array
    // and see if the index for the button matches the index of the correct
    // answer.

    @IBAction func didTapAnswerButton(button: UIButton) {
        unhideEndLabelAndNextButton()

        let buttonIndex = buttons.indexOf(button)
        let questionObject = questions[questionIndexes[currentQuestionIndex]]

        if buttonIndex == questionObject.correctAnswer {
            endLabel.text = "Correcto"
        } else {
            endLabel.text = "Falso"
        }
    }

    @IBAction func didTapNextButton(sender: AnyObject) {
        updateLabelsAndButtonsForIndex(currentQuestionIndex + 1)
    }

}

那里埋藏了很多,所以如果你不完全遵循这里发生的一切,我不会担心细节。但关键是,在你的模型中构建一个索引数组,将其洗牌,然后你可以继续迭代这个混洗数组,你保证你不会再问两次相同的问题。


2
投票

尝试以下代码,希望它适合您

class ViewController: UIViewController {

@IBOutlet weak var QuestionLabel: UILabel!
@IBOutlet weak var Button1: UIButton!
@IBOutlet weak var Button2: UIButton!
@IBOutlet weak var Button3: UIButton!
@IBOutlet weak var Button4: UIButton!
@IBOutlet weak var Next: UIButton!
@IBOutlet weak var LabelEnd: UILabel!

var CorrectAnswer = String()
var randomQuestionArray:[Int] = [1, 2, 3, 4]

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

    Hide()
    RamdomQuestions()
}

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

func RamdomQuestions () {

    let randomIndex = Int(arc4random_uniform(UInt32(randomQuestionArray.count)))

    if randomQuestionArray.count > 0 {

    switch (randomQuestionArray[randomIndex]) {

    case 1:
        QuestionLabel.text = "Hola familia, Cual es mi nombre? "
        Button1.setTitle ("Cesar", forState: UIControlState.Normal)
        Button2.setTitle ("Karlos", forState: UIControlState.Normal)
        Button3.setTitle ("William", forState: UIControlState.Normal)
        Button4.setTitle ("Chiqui", forState: UIControlState.Normal)
        CorrectAnswer = "2"
        break

    case 2:
        QuestionLabel.text = "Hola famili, cual es mi apellido? "
        Button1.setTitle ("Perez", forState: UIControlState.Normal)
        Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
        Button3.setTitle ("Garcia", forState: UIControlState.Normal)
        Button4.setTitle ("Sanchez", forState: UIControlState.Normal)
        CorrectAnswer = "1"
        break

    case 3:
        QuestionLabel.text = "Quien hace la lachona mas rica? "
        Button1.setTitle ("Willy", forState: UIControlState.Normal)
        Button2.setTitle ("Mario", forState: UIControlState.Normal)
        Button3.setTitle ("Karlos", forState: UIControlState.Normal)
        Button4.setTitle ("Juan David", forState: UIControlState.Normal)
        CorrectAnswer = "1"
        break

    case 4:
        QuestionLabel.text = "Quien hace las tartas mas lindas"
        Button1.setTitle ("Jili", forState: UIControlState.Normal)
        Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
        Button3.setTitle ("Garcia", forState: UIControlState.Normal)
        Button4.setTitle ("Leidy y Liz", forState: UIControlState.Normal)
        CorrectAnswer = "4"
        break

    default:
        break

    }
        randomQuestionArray.removeAtIndex(randomIndex)
    }


}

func Hide () {
    LabelEnd.hidden = true
    Next.hidden = true
}

func UnHide () {
    LabelEnd.hidden = false
    Next.hidden = false
}

@IBAction func Button1Action(sender: AnyObject) {
    UnHide()
    if (CorrectAnswer == "1") {
        LabelEnd.text = "Correcto"
    } else{
        LabelEnd.text = "Falso"
    }
}

func Button2Action(sender: AnyObject) {
    UnHide()
    if (CorrectAnswer == "2") {
        LabelEnd.text = "Correcto"
    } else{
        LabelEnd.text = "Falso"
    }
}

func Button3Action(sender: AnyObject) {
    UnHide()
    if (CorrectAnswer == "3") {
        LabelEnd.text = "Correcto"
    } else{
        LabelEnd.text = "Falso"
    }
}

func Button4Action(sender: AnyObject) {
    UnHide()
    if (CorrectAnswer == "4") {
        LabelEnd.text = "Correcto"
    } else{
        LabelEnd.text = "Falso"
    }
}

@IBAction func Next(sender: AnyObject) {
    RamdomQuestions()
}

}

0
投票

我最初连接了

@IBAction func didTapAnswerButton(button:

@IBAction func didTapNextButton(sender:

到五个按钮和模拟器没有在屏幕上显示正确或错误。

我再试一次,只是连接了

@IBAction func didTapAnswerButton(button:

到五个按钮和

@IBAction func didTapNextButton(sender:

到下一步按钮,它工作。

© www.soinside.com 2019 - 2024. All rights reserved.