使测验应用程序不重复随机问题

Make Quiz App Not Repeat Random Questions

我知道有一些 shuffle 或类似的解决方案,但我不知道是否可以在我的代码中应用它们。你能帮我么?如何让题目不重复?

func RandomQuestions(){

    var RandomNumber = arc4random() % 28
    RandomNumber += 1

    switch(RandomNumber){
    case 1:
        QuestionLabel.text = "Who is the Numer One Best DJ According to DJ Mag 2014?"
        Button1.setTitle("Tiësto", forState: UIControlState.Normal)
        Button2.setTitle("Avicii", forState: UIControlState.Normal)
        Button3.setTitle("Hardwell", forState: UIControlState.Normal)
        Button4.setTitle("Dimitri Vegas & Like Mike", forState: UIControlState.Normal)
        CorrectAnwser = "3"
        break
    case 2:
        QuestionLabel.text = "Who is the Only DJ that played in an Olimpic Games?"
        Button1.setTitle("Avicii", forState: UIControlState.Normal)
        Button2.setTitle("Tiësto", forState: UIControlState.Normal)
        Button3.setTitle("Armin Van Buuren", forState: UIControlState.Normal)
        Button4.setTitle("Calvin Harris", forState: UIControlState.Normal)
        CorrectAnwser = "2"
        break
    }

    /* ...more questions...* /

}

我的 给另一个 post:

var someArray = Array(1...28)

let index = Int(arc4random_uniform(UInt32(someArray.count)))
let randomNumber = someArray[index]

someArray.removeAtIndex(index)

然后您可以将 randomNumber 传递给您的函数:

func randomQuestions(question: Int) {
    switch(question) {
    case 1: // Question1
    case 2: // Question2
}

试图让arc4random()不重复并不是看待这个问题的正确方式。你想避免问同一个问题两次,所以你需要以某种方式跟踪你已经问过的问题。我建议使用一个数组,也许给每个问题某种类型的 ID,然后将每个问题的 ID 存储在数组中,并在被问到时删除它们或将它们移动到新的 "asked questions" 数组中。

我会添加一个变量来保存已经向视图控制器提出的问题:

var askedQuestions = [Int]()

然后,在您的函数中,您可以执行以下操作:

func RandomQuestions(){

    var randomNumber:Int = (Int)(arc4random() % 28 + 1)

    while find(askedQuestions, randomNumber) != nil && askedQuestions.count < 28 {
        randomNumber = (Int)(arc4random() % 28 + 1)
    }

    if askedQuestions.count > 28 {
        return
    }

    askedQuestions.append(randomNumber)

    switch(randomNumber){
    case 1:
        QuestionLabel.text = "Who is the Numer One Best DJ According to DJ Mag 2014?"
        Button1.setTitle("Tiësto", forState: UIControlState.Normal)
        Button2.setTitle("Avicii", forState: UIControlState.Normal)
        Button3.setTitle("Hardwell", forState: UIControlState.Normal)
        Button4.setTitle("Dimitri Vegas & Like Mike", forState: UIControlState.Normal)
        CorrectAnwser = "3"
        break
    case 2:
        QuestionLabel.text = "Who is the Only DJ that played in an Olimpic Games?"
        Button1.setTitle("Avicii", forState: UIControlState.Normal)
        Button2.setTitle("Tiësto", forState: UIControlState.Normal)
        Button3.setTitle("Armin Van Buuren", forState: UIControlState.Normal)
        Button4.setTitle("Calvin Harris", forState: UIControlState.Normal)
        CorrectAnwser = "2"
        break
    }

    /* ...more questions...*/

}

另请注意,当您在所有 28 个问题中 运行 时,您必须注意会发生什么。 :)

PS:最好不要像RandomNumber那样使用大写的变量名。请改用 randomNumber。这是很好的做法。 :)

最糟糕的解决方法是不断生成随机数和 "keep track" 已经使用过的数字。对于 100 个问题的数组,您必须平均滚动最后一个随机数 100 次才能获得最后一个可用问题。

执行此类操作的最简单方法是在使用数组之前随机排列数组,然后按顺序遍历它。

您可以在这个答案中看到 Fisher-Yates 洗牌的实现... How do I shuffle an array in Swift?

那么就是迭代数组的情况了...

for question in shuffledArray {
    // ask question
}

你甚至可以为它创建一个生成器,让你得到 next 问题等等。

此外,您使用开关并打开随机值的方式是错误的。

创建一个具有以下属性的问题对象...questionText、option1、option2、correctAnswer...等...

您甚至可以创建一个选项数组并将 correctAnswerIndex 存储在它旁边。

然后将所有问题对象粘贴到一个数组中。更好的是,将它们放在一个 plist 文件中,以便您可以在运行时读取它们。那样更容​​易管理。

您的代码需要重新格式化,保持这种方式(您建议的代码)您最终会添加大量每次需要添加新问题时都编写代码。请考虑这样做:

class Question{
 let question : String
 let optionA: String
 let optionB: String
 let optionC: String
 let optionD: String
 let correctAnswer: Int

 //add initializers here.
}

class Question{
 let question : String
 let options: [String]
 let correctAnswer: Int

 //add initializers here.
}

然后

class QuestionRepository{
 private var questions: [Question]

 /// use this to load questions to be asked only once per game, this way you will end up having the order in which you will ask questions and there will be no repetitions.
 var readyToAskQuestions : [Question] {
    let shuffledQuestions = shuffle(questions)
    return shuffledQuestions
 }      

 init()
  {
    //build your harcoded 'questions' variable here 
  }

 convenience init(url: String)
 {
   //or load your questions from a file, NSUserDefaults, database sql file, from a webservice on the internet, etc.. 
 }
} 

Shuffle function stated here can be any of the stated as answers at sorting arrays in swift