Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove/exclude enum cases in Swift

Tags:

ios

swift

This is a struct that contains the operations enabled in the game:

struct OperationsEnabled {
    var addition = 1
    var subtraction = 0 // disabled
    var multiplication = 1
    var division = 1
}

This is the enum I use to generate simple arithmetic questions:

enum BinaryOperation: String {
    case Addition = "+"
    case Subtraction = "-"
    case Multiplication = "×"
    case Division = "÷"

    func rangesForDifficulty(difficulty: Difficulty) -> (Range<Int>, Range<Int>) {
        switch self {
        case .Addition:
            switch difficulty {
            case .Easy: return (1...10, 1...10)
            case .Intermediate: return (10...100, 1...100)
            case .Difficult: return (109...999, 109...999)
            }
        case .Subtraction:
            switch difficulty {
            case .Easy: return (1...10, 1...10)
            case .Intermediate: return (10...100, 1...100)
            case .Difficult:  return (109...999, 109...999)
            }
        case .Multiplication:
            switch difficulty {
            case .Easy: return (1...10, 2...4)
            case .Intermediate: return (1...50, 3...7)
            case .Difficult: return (10...100, 4...15)
            }
        case .Division:
            switch difficulty {
            case .Easy: return (1...10, 2...4)
            case .Intermediate: return (1...50, 3...7)
            case .Difficult: return (10...100, 4...15)
            }
        }
    }

    func apply(number1: Int, _ number2: Int) -> Int {
        switch self {
        case .Addition:
            return number1 + number2
        case .Subtraction:
            return number1 - number2
        case .Multiplication:
            return number1 * number2
        case .Division:
            return number1 / number2
        }
    }
}

// Let's make a new question
func newQuestion() {
    let (range1, range2) = binaryOperation.rangesForDifficulty(difficulty)
    let number1 = Int.random(range1)
    let number2 = Int.random(range2)
    let answer = binaryOperation.apply(number1, number2)
}

I want to filter out the operations. For example, I need to exclude the operations not allowed in the game, but there seems to be no way to use conditionals in here. How can I do it?

like image 342
Cesare Avatar asked Feb 10 '26 21:02

Cesare


1 Answers

You want to choose a random operation from the available operations. Create an initializer for BinaryOperation that takes OperationsEnabled and creates a BinaryOperation.

init?(enabled: OperationsEnabled) {
    let all: [(BinaryOperation, Int)] = [(.Addition, enabled.addition), (.Subtraction, enabled.subtraction),
             (.Multiplication, enabled.multiplication), (.Division, enabled.division)]
    let avail = all.flatMap { (op, on) in on == 1 ? op : nil }
    if avail.isEmpty {
        return nil
    }
    else {
        let index = Int(arc4random_uniform(UInt32(avail.count)))
        self = avail[index]
    }
}

Usage:

let enabled = OperationsEnabled(addition: 1, subtraction: 1, multiplication: 0, division: 0)
let binaryOperation = BinaryOperation(enabled: enabled)!    

Notes:

  1. This works by first creating a paired list of tuples that contain an operation paired with its availability.
  2. flatMap is used to select just those operations that are available.
  3. If none of the operations were marked as available, then avail will be empty and this failable initializer will return nil.
  4. The operation is chosen randomly from the list of available operations.
like image 59
vacawama Avatar answered Feb 12 '26 15:02

vacawama