-3

I am trying to make random questions appear in my quiz. Right now I am using arc4random() to pull a random number for a switch statement and that's what's displayed on buttons and the labels but it likes to duplicate the questions quite a bit. How can I stop that from happening or make it so it duplicates less?

Yes I know I tend to duplicate code a lot but that's what I know how to do at the moment!

func RandomQuestions() {
    var RandomNumber = arc4random() % 10
    var RandomQuestion = arc4random() % 4
    RandomQuestion += 1
    RandomNumber += 1
    Next.isHidden = true

    switch(RandomNumber) {

    case 1:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "What is the tail end of a piece of music?"
            button1.setTitle("Coda", for: UIControl.State.normal)
            button2.setTitle("Da Capo", for: UIControl.State.normal)
            button3.setTitle("Forte", for: UIControl.State.normal)
            button4.setTitle("Largo", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "What is the tail end of a piece of music?"
            button1.setTitle("Da Capo", for: UIControl.State.normal)
            button2.setTitle("Largo", for: UIControl.State.normal)
            button3.setTitle("Coda", for: UIControl.State.normal)
            button4.setTitle("Forte", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "What is the tail end of a piece of music?"
            button1.setTitle("Largo", for: UIControl.State.normal)
            button2.setTitle("Da Capo", for: UIControl.State.normal)
            button3.setTitle("Forte", for: UIControl.State.normal)
            button4.setTitle("Coda", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "What is the tail end of a piece of music?"
            button1.setTitle("Largo", for: UIControl.State.normal)
            button2.setTitle("Coda", for: UIControl.State.normal)
            button3.setTitle("Forte", for: UIControl.State.normal)
            button4.setTitle("Da Capo", for: UIControl.State.normal)
            CorrectAnswer = "2"
        }
        break
    case 2:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Another name for Majestically?"
            button1.setTitle("Lunga", for: UIControl.State.normal)
            button2.setTitle("Dolce", for: UIControl.State.normal)
            button3.setTitle("Maestoso", for: UIControl.State.normal)
            button4.setTitle("Molto", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Another name for Majestically?"
            button1.setTitle("Dolce", for: UIControl.State.normal)
            button2.setTitle("Lunga", for: UIControl.State.normal)
            button3.setTitle("Molto", for: UIControl.State.normal)
            button4.setTitle("Maestoso", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Another name for Majestically?"
            button1.setTitle("Molto", for: UIControl.State.normal)
            button2.setTitle("Maestoso", for: UIControl.State.normal)
            button3.setTitle("Lunga", for: UIControl.State.normal)
            button4.setTitle("Dolce", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else {
            questionLabel.text = "Another name for Majestically?"
            button1.setTitle("Maestoso", for: UIControl.State.normal)
            button2.setTitle("Dolce", for: UIControl.State.normal)
            button3.setTitle("Lunga", for: UIControl.State.normal)
            button4.setTitle("Molto", for: UIControl.State.normal)
            CorrectAnswer = "1"
        }
        break
    case 3:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Another name for Time/Speed?"
            button1.setTitle("Largo", for: UIControl.State.normal)
            button2.setTitle("Soli", for: UIControl.State.normal)
            button3.setTitle("Tenuto", for: UIControl.State.normal)
            button4.setTitle("Tempo", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Another name for Time/Speed?"
            button1.setTitle("Soli", for: UIControl.State.normal)
            button2.setTitle("Tenuto", for: UIControl.State.normal)
            button3.setTitle("Tempo", for: UIControl.State.normal)
            button4.setTitle("Largo", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Another name for Time/Speed?"
            button1.setTitle("Tempo", for: UIControl.State.normal)
            button2.setTitle("Largo", for: UIControl.State.normal)
            button3.setTitle("Soli", for: UIControl.State.normal)
            button4.setTitle("Tenuto", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else {
            questionLabel.text = "Another name for Time/Speed?"
            button1.setTitle("Largo", for: UIControl.State.normal)
            button2.setTitle("Tempo", for: UIControl.State.normal)
            button3.setTitle("Tenuto", for: UIControl.State.normal)
            button4.setTitle("Soli", for: UIControl.State.normal)
            CorrectAnswer = "2"
        }
        break
    case 4:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Another name for Softly"
            button1.setTitle("Piano", for: UIControl.State.normal)
            button2.setTitle("Forte", for: UIControl.State.normal)
            button3.setTitle("Segno", for: UIControl.State.normal)
            button4.setTitle("Tacet", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Another name for Softly"
            button1.setTitle("Forte", for: UIControl.State.normal)
            button2.setTitle("Tacet", for: UIControl.State.normal)
            button3.setTitle("Piano", for: UIControl.State.normal)
            button4.setTitle("Segno", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Another name for Softly"
            button1.setTitle("Tacet", for: UIControl.State.normal)
            button2.setTitle("Segno", for: UIControl.State.normal)
            button3.setTitle("Forte", for: UIControl.State.normal)
            button4.setTitle("Piano", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "Another name for Softly"
            button1.setTitle("Forte", for: UIControl.State.normal)
            button2.setTitle("Piano", for: UIControl.State.normal)
            button3.setTitle("Segno", for: UIControl.State.normal)
            button4.setTitle("Tacet", for: UIControl.State.normal)
            CorrectAnswer = "2"
        }
        break
    case 5:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Another name for Really Fast?"
            button1.setTitle("Staccato", for: UIControl.State.normal)
            button2.setTitle("Fermata", for: UIControl.State.normal)
            button3.setTitle("Presto", for: UIControl.State.normal)
            button4.setTitle("Mezzo", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Another name for Really Fast?"
            button1.setTitle("Fermata", for: UIControl.State.normal)
            button2.setTitle("Presto", for: UIControl.State.normal)
            button3.setTitle("Staccato", for: UIControl.State.normal)
            button4.setTitle("Mezzo", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Another name for Really Fast?"
            button1.setTitle("Fermata", for: UIControl.State.normal)
            button2.setTitle("Mezzo", for: UIControl.State.normal)
            button3.setTitle("Staccato", for: UIControl.State.normal)
            button4.setTitle("Presto", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "Another name for Really Fast?"
            button1.setTitle("Presto", for: UIControl.State.normal)
            button2.setTitle("Mezzo", for: UIControl.State.normal)
            button3.setTitle("Staccato", for: UIControl.State.normal)
            button4.setTitle("Fermata", for: UIControl.State.normal)
            CorrectAnswer = "1"
        }
    case 6:
        if RandomQuestion == UInt(1) {
            questionLabel.text = "Another way to say From The Beginning?"
            button1.setTitle("Da Capo", for: UIControl.State.normal)
            button2.setTitle("Molto", for: UIControl.State.normal)
            button3.setTitle("Dal Segno", for: UIControl.State.normal)
            button4.setTitle("Al Fine", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt(2) {
            questionLabel.text = "Another way to say From The Beginning?"
            button1.setTitle("Al Fine", for: UIControl.State.normal)
            button2.setTitle("Da Capo", for: UIControl.State.normal)
            button3.setTitle("Molto", for: UIControl.State.normal)
            button4.setTitle("Dal Segno", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else if RandomQuestion == UInt(3) {
            questionLabel.text = "Another way to say From The Beginning?"
            button1.setTitle("Molto", for: UIControl.State.normal)
            button2.setTitle("Al Fine", for: UIControl.State.normal)
            button3.setTitle("Dal Segno", for: UIControl.State.normal)
            button4.setTitle("Da Capo", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "Another way to say From The Beginning?"
            button1.setTitle("Al Fine", for: UIControl.State.normal)
            button2.setTitle("Molto", for: UIControl.State.normal)
            button3.setTitle("Da Capo", for: UIControl.State.normal)
            button4.setTitle("Dal Segno", for: UIControl.State.normal)
            CorrectAnswer = "3"
        }
    case 7:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "In a singing style"
            button1.setTitle("Cantabile", for: UIControl.State.normal)
            button2.setTitle("Diminuendo", for: UIControl.State.normal)
            button3.setTitle("Animato", for: UIControl.State.normal)
            button4.setTitle("Chromatic", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "In a singing style"
            button1.setTitle("Chromatic", for: UIControl.State.normal)
            button2.setTitle("Diminuendo", for: UIControl.State.normal)
            button3.setTitle("Animato", for: UIControl.State.normal)
            button4.setTitle("Cantabile", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "In a singing style"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Chromatic", for: UIControl.State.normal)
            button3.setTitle("Cantabile", for: UIControl.State.normal)
            button4.setTitle("Animato", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else {
            questionLabel.text = "In a singing style"
            button1.setTitle("Animato", for: UIControl.State.normal)
            button2.setTitle("Cantabile", for: UIControl.State.normal)
            button3.setTitle("Chromatic", for: UIControl.State.normal)
            button4.setTitle("Diminuendo", for: UIControl.State.normal)
            CorrectAnswer = "2"
        }
    case 8:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Which also means From The Sign?"
            button1.setTitle("Dal Segno", for: UIControl.State.normal)
            button2.setTitle("Da Capo", for: UIControl.State.normal)
            button3.setTitle("Grave", for: UIControl.State.normal)
            button4.setTitle("Lento", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Which also means From The Sign?"
            button1.setTitle("Lento", for: UIControl.State.normal)
            button2.setTitle("Dal Segno", for: UIControl.State.normal)
            button3.setTitle("Da Capo", for: UIControl.State.normal)
            button4.setTitle("Grave", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Which also means From The Sign?"
            button1.setTitle("Lento", for: UIControl.State.normal)
            button2.setTitle("Grave", for: UIControl.State.normal)
            button3.setTitle("Da Capo", for: UIControl.State.normal)
            button4.setTitle("Dal Segno", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "Which also means From The Sign?"
            button1.setTitle("Da Capo", for: UIControl.State.normal)
            button2.setTitle("Lento ", for: UIControl.State.normal)
            button3.setTitle("Dal Segno", for: UIControl.State.normal)
            button4.setTitle("Grave", for: UIControl.State.normal)
            CorrectAnswer = "3"
        }
    case 9:
        if RandomQuestion == UInt(1) {
            questionLabel.text = "Which also means The Same As?"
            button1.setTitle("Simile", for: UIControl.State.normal)
            button2.setTitle("Rubato", for: UIControl.State.normal)
            button3.setTitle("Non Troppo", for: UIControl.State.normal)
            button4.setTitle("Mosso", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Which also means The Same As?"
            button1.setTitle("Mosso", for: UIControl.State.normal)
            button2.setTitle("Non Troppo", for: UIControl.State.normal)
            button3.setTitle("Rubato", for: UIControl.State.normal)
            button4.setTitle("Simile", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Which also means The Same As?"
            button1.setTitle("Rubato", for: UIControl.State.normal)
            button2.setTitle("Simile", for: UIControl.State.normal)
            button3.setTitle("Non Troppo", for: UIControl.State.normal)
            button4.setTitle("Mosso", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else {
            questionLabel.text = "Which also means The Same As?"
            button1.setTitle("Rubato", for: UIControl.State.normal)
            button2.setTitle("Mosso", for: UIControl.State.normal)
            button3.setTitle("Simile", for: UIControl.State.normal)
            button4.setTitle("Non Troppo", for: UIControl.State.normal)
            CorrectAnswer = "3"
        }
    case 10:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Which also means Gradually Get Louder?"
            button1.setTitle("Crescendo", for: UIControl.State.normal)
            button2.setTitle("Decrescendo", for: UIControl.State.normal)
            button3.setTitle("Diminuendo", for: UIControl.State.normal)
            button4.setTitle("Mezzo Forte", for: UIControl.State.normal)
            CorrectAnswer = "1"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Which also means Gradually Get Louder?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button3.setTitle("Crescendo", for: UIControl.State.normal)
            button4.setTitle("Decrescendo", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Which also means Gradually Get Louder?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Crescendo", for: UIControl.State.normal)
            button3.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button4.setTitle("Decrescendo", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else {
            questionLabel.text = "Which also means Gradually Get Louder?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Decrescendo", for: UIControl.State.normal)
            button3.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button4.setTitle("Crescendo", for: UIControl.State.normal)
            CorrectAnswer = "4"
        }
    case 11:
        if RandomQuestion == UInt32(1) {
            questionLabel.text = "Which also means Gradually Get Softer?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Decrescendo", for: UIControl.State.normal)
            button3.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button4.setTitle("Crescendo", for: UIControl.State.normal)
            CorrectAnswer = "2"
        } else if RandomQuestion == UInt32(2) {
            questionLabel.text = "Which also means Gradually Get Softer?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button3.setTitle("Decrescendo", for: UIControl.State.normal)
            button4.setTitle("Crescendo", for: UIControl.State.normal)
            CorrectAnswer = "3"
        } else if RandomQuestion == UInt32(3) {
            questionLabel.text = "Which also means Gradually Get Softer?"
            button1.setTitle("Diminuendo", for: UIControl.State.normal)
            button2.setTitle("Mezzo Forte", for: UIControl.State.normal)
            button3.setTitle("Crescendo", for: UIControl.State.normal)
            button4.setTitle("Decrescendo", for: UIControl.State.normal)
            CorrectAnswer = "4"
        } else {
            questionLabel.text = "Which also means Gradually Get Louder?"
            button1.setTitle("Decrescendo", for: UIControl.State.normal)
            button2.setTitle("Crescendo", for: UIControl.State.normal)
            button3.setTitle("Diminuendo", for: UIControl.State.normal)
            button4.setTitle("Mezzo Forte", for: UIControl.State.normal)
            CorrectAnswer = "1"
        }
    default:

        break
    }
}
Cal
  • 422
  • 6
  • 20
Schmob
  • 9
  • 3
  • What do you mean it duplicates questions quite a bit? Like `randomNumber` is the same frequently? – impression7vx Jan 01 '19 at 03:02
  • 2
    Duplicates are a fact of life with random numbers. They simply happen. If you want the numbers to be chosen that are spread across your possible questions without repeats then you don’t actually want randomness. Think about putting your questions into an array, choose one at random, then remove that question from the array and use it in your app. Next time you choose a random question you know your choosing from unused questions. Repeat. – Magnas Jan 01 '19 at 04:31
  • @Magnas Thats a good idea. I'll have to try that. – Schmob Jan 01 '19 at 06:07

1 Answers1

0

First of all arc4random() has become obsolete in Swift 4.2+.

There are random(in class methods for all numeric types and shuffled() and randomElement() to get random elements from an array.

To get an unique random element from an array you can use a simple function which picks a random element and then removes this item from the array.

Assuming you have 10 questions

let numberOfQuestions = 10

create an index array

var indexArray = [Int](0..<numberOfQuestions)

and use this function

func uniqueRandomElement(from array: inout [Int]) -> Int? {
    guard let random = array.randomElement() else { return nil }
    let index = array.firstIndex(of: random)!
    array.remove(at: index)
    return random
}

let index = uniqueRandomElement(from: &indexArray)

It returns the random index or nil if all questions have been asked.


The code can be dramatically reduced if you organize the questions in a struct

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

let questions = [Question(question: "What is the tail end of a piece of music?", answers: ["Coda", "Da Capo", "Forte", "Largo"], correctAnswer: "Coda"),
                 ...
                 ...
                 Question(question: "Which also means Gradually Get Softer?", answers: ["Ritardando", "Decrescendo", "Mezzo Forte", "Crescendo"], correctAnswer: "Decrescendo")]

Declare an empty array for the indices

var indexArray = [Int]()

and a function to reset the array by populating it with all question indices

func resetQuestions() {
    indexArray = [Int](0..<questions.count)
}

randomQuestion gets a new index with the uniqueRandomElement function, shuffles the answers array and assigns the values to the buttons. It returns the current question

func randomQuestion() -> Question? {
    guard let questionIndex = uniqueRandomElement(from: &indexArray) else {
        Next.isHidden = true
        return nil
    }

    let currentQuestion = questions[questionIndex]
    let shuffledAnswers = currentQuestion.answers.shuffled()
    button1.setTitle(shuffledAnswers[0], for: .normal)
    button2.setTitle(shuffledAnswers[1], for: .normal)
    button3.setTitle(shuffledAnswers[2], for: .normal)
    button4.setTitle(shuffledAnswers[3], for: .normal)
    return currentQuestion
}

Now compare the title of the pressed button with currentQuestion.correctAnswer.

Side note: As Decrescendo and Diminuendo are actually synonyms better use something like Ritardando in the Gradually Get Softer question

vadian
  • 274,689
  • 30
  • 353
  • 361