Loca Girl
Loca Girl

Reputation: 63

Encountering "Fatal error: Index fell out of range" error when random number is generated

I'm trying to create a bingo number generator app, however after generating numbers "Fatal error: Index fell out of range" was encountered randomly on line "let letter = prefixes[bingoBall/15]".

var numbersSeen = Set<Int>()
var prefixes = ["B-", "I-", "N-", "G-", "O-"]

func randomNumber() -> Int {

    var nextNum : Int
    repeat {
        nextNum = Int.random(in: 1...75)

        if !numbersSeen.contains(nextNum) {
            numbersSeen.insert(nextNum)
            return Int(nextNum)
        }

    } while true
}

func randomBall() {
    let bingoBall = randomNumber()
    let letter = prefixes[bingoBall/15]
    lblNumber.text = "\(letter)\(bingoBall)"

    lblNumCalled.text = String(numbersSeen.count) + " numbers called."
    lblNumRemain.text = String(75 - numbersSeen.count) + " numbers remaining."

    if lblNumPrev.text != "" {
        lblNumPrev.text = lblNumPrev.text!+", "+lblNumber.text!
    }else{
        lblNumPrev.text = lblNumber.text!
    }
}

Upvotes: 1

Views: 78

Answers (3)

Joakim Danielson
Joakim Danielson

Reputation: 51971

I think the easiest solution to this while still generating bingo numbers between 1 and 75 is to subtract one before doing the division when accessing the letter array

let letter = prefixes[(bingoBall - 1)/15]

This means we have numbers in the range 0-74 which when divided by 15 creates numbers in the range 0-4 which is a valid range for an array of size 5

Upvotes: 1

Sahil Manchanda
Sahil Manchanda

Reputation: 10012

Array Indices Start from Zero, Dividing by 15 or arbitrary number could generate an index position which is not available thus Index Out of Bounds exception. A possible solution which gives you the freedom to generate a random number from any given range:

let letter = prefixes[bingoBall % numbersSeen.count]

Upvotes: 1

PGDev
PGDev

Reputation: 24341

Reason for the issue:

Since the array indices start from 0, so the indices of prefixes array will vary from 0...4.

And the range that you're using for generating randomNumber is from 1...75.

So the bingoBall/15 will give 5 when bingoBall = 75.

Now, accessing prefixes[5] will result in Index Out of Bounds exception.

Solution:

1. Change the range of generating the randomNumber, i.e.

nextNum = Int.random(in: 1...60)

2. Change the division factor such that it result in a value <=4, example,

let letter = prefixes[bingoBall/18]

Upvotes: 0

Related Questions