Looping with buttons

(Faris) #1

I might be breaking some rule with my message but please excuse me for my first time login!

After months of studying swift, I thought I'm able to start my first simple app! But seems the reality is different from my thoughts!

What I need to do is a testing app, the interface has 3 buttons, the app will ask a question e.g. 3x6, the right answer goes to one of the buttons in random order, while the other buttons will be filled with other random numbers!

I tried to do it by taking two numbers from two random generators (num1 and num2), take these two numbers to say(3 and 6) and display it in one of the buttons. At this point where I got messing around, first, how to take the last two numbers and fill it in remaining buttons, second, I have a vague idea is to use a loop which representing the buttons where I got lost when I tried it :(

I have struggled with this problem for a few weeks trying different approaches but at the end, I go to the same problems which I mentioned above.

Your help highly appreciated!



(Jeremy David Giesbrecht) #2

Welcome to the forums!

It can be helpful when asking questions to post the code you do have, even if it doesn’t work. It helps the rest of the world understand the question.

But since you haven’t, I’ll just post what I would write if I were trying to accomplish that. Hopefully the answer to your question is in there somewhere. For the sake of your own satisfaction, don’t just copy and paste what I did. Learn from it, but then stick with what you have and adjust it until it works. If you have Xcode, you can watch the following execute by pasting it into a playground:

/// Defines the highest factor we want to ask about.
/// (Since 45 645 648 906 584 × 456 048 564 485 would probably be cruel.)
let maximumFactor = 10

/// The highest product that will ever be correct.
let maximumProduct = maximumFactor * maximumFactor

/// A multiple choice‐option.
struct MultipleChoiceOption {
    /// The number to display as the option.
    let number: Int
    /// Whether or not the option is the correct one.
    let isCorrect: Bool

/// A multiplication question.
struct MultiplicationQuestion {
    /// The multiplier (first factor).
    let multiplier: Int
    /// The multiplicand (second factor).
    let multiplicand: Int
    /// The product (answer).
    let product: Int
    /// The options to choose from.
    let options: [MultipleChoiceOption]
    /// Creates a question from two factors.
    init(multiplier: Int, multiplicand: Int) {
        self.multiplier = multiplier
        self.multiplicand = multiplicand
        let product = multiplier * multiplicand
        self.product = product
        var options: [MultipleChoiceOption] = []
        let correct = MultipleChoiceOption(number: product, isCorrect: true)
        while options.count < 3 { // Keep adding incorrect answers until there are 3.
            let random = Int.random(in: 0 ... maximumProduct)
            if !options.contains(where: { $0.number == random }) { // We don’t want duplicates.
                let incorrect = MultipleChoiceOption(number: random, isCorrect: false)
        self.options = options.shuffled()
    /// Creates a random question (limited by `maximumFactor`).
    static func random() -> MultiplicationQuestion {
        let multiplier = Int.random(in: 0 ... maximumFactor)
        let multiplicand = Int.random(in: 0 ... maximumFactor)
        return MultiplicationQuestion(multiplier: multiplier, multiplicand: multiplicand)

// Say there was an array of 3 buttons somewhere else like this, but with buttons not text:
let buttons: [Any] = ["Button", "Button", "Button"]

/// Displays a question.
func ask(_ question: MultiplicationQuestion) {
    // This just prints it as text output.
    // Your application will need to display these in UI elements.
    print("\(question.multiplier) × \(question.multiplicand)")
    for (option, button) in zip(question.options, buttons) {
        // You can use the corresponding `button` here,
        // but since ours are just dummies, we won’t.
        print("• \(option.number)?")

let question = MultiplicationQuestion.random()


/// This checks the answer.
/// Interface buttons will have to call it with their respective index.
func answer(_ question: MultiplicationQuestion, withOption optionIndex: Int) {
    let option = question.options[optionIndex]
    if option.isCorrect {
        print("\(question.multiplier) × \(question.multiplicand) = \(option.number) ✓")
    } else {
        print("\(question.multiplier) × \(question.multiplicand) ≠ \(option.number) ✗")
        print("\(question.multiplier) × \(question.multiplicand) = \(question.product)")

// Buttons would do the following:
// (But because the playground doesn’t have buttons, we’ll always answer with the first one.)
answer(question, withOption: 0)