Argument Out Of Range for random number selector

This is what I am working on: I am currently creating a Bingo game. I have made a list with all possible numbers and assign the letter based on the number chosen.

This is the issue that I am having: after maybe 15 numbers are chosen I get this error and the whole thing freezes up. I’m not sure how it’s trying to choose something beyond the scope of the list. It’s not a negative number so I know it’s not that.

Here is the code that I’ve come up with so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class NumberGenerator : MonoBehaviour
{
    #region Variables

    [SerializeField] List<int> bingoNumberList;
    [SerializeField] List<int> calledNumberList;

    [SerializeField] Text calloutText;

    int currentNumber;
    char currentLetter;

    #endregion

    #region GameStart

    private void Start()
    {
        for (int i = 1; i < 76; i++)
        {
            bingoNumberList.Add(i);
        }

        StartCoroutine(PlayBingo());
    }

    IEnumerator PlayBingo()
    {
        while (bingoNumberList.Count > 0)
        {
            NumberSelection();

            yield return new WaitForSeconds(1f);
        }

        yield return null;
    }

    #endregion

    #region Core

    private void Update()
    {
        CalloutText();
    }

    private void NumberSelection()
    {

        if (bingoNumberList.Count > 0)
        {
            int randomIndex = bingoNumberList[Random.Range(0, bingoNumberList.Count)];
            currentNumber = bingoNumberList[randomIndex];

            LetterSelection();

            Debug.Log(currentNumber);
            Debug.Log(currentLetter);

            calledNumberList.Add(currentNumber);
            bingoNumberList.Remove(bingoNumberList[randomIndex]);
        }
        else
        {
            Debug.Log("All balls have been called!");
        }
    }

    private void LetterSelection()
    {
        if (currentNumber >= 1 && currentNumber <= 15)
        {
            currentLetter = 'B';
        }
        else if (currentNumber >= 16 && currentNumber <= 30)
        {
            currentLetter = 'I';
        }
        else if (currentNumber >= 31 && currentNumber <= 45)
        {
            currentLetter = 'N';
        }
        else if (currentNumber >= 46 && currentNumber <= 60)
        {
            currentLetter = 'G';
        }
        else
        {
            currentLetter = 'O';
        }
    }

    #endregion

    #region CalloutText

    public void CalloutText()
    {
        calloutText.text = "The current ball is " + currentLetter + currentNumber + "!";
    }

    #endregion
}

Well, those two lines do not make much sense:

int randomIndex = bingoNumberList[Random.Range(0, bingoNumberList.Count)];
currentNumber = bingoNumberList[randomIndex];

Note that your “randomIndex” is not a random index into the bingoNumberList, but it’s one of the elements of the bingoNumberList.

Just think about your logic for a moment. Imagine you have 5 elements

// 1, 2, 3, 4, 5

You roll a random number between 0 and 4 and grab that element as index, say we roll a “2”. That means you would remove element 2 from the array so your array would now look like this:

// 1, 2, 4, 5

Since you use the picked element as index, this will fail when you pick a number that is higher than the remaining elements. For example if in the second run we randomly pick the last element (element with index 3 which has a value of “5”), you then would use the value (5) as index into that list. However the list only contains 4 elements at this point so the highest valid index is 3.

So you probably wanted to do:

int randomIndex = Random.Range(0, bingoNumberList.Count);

instead. Also when you have the index of an element you want to remove, it’s way better to use RemoveAt instead of Remove.

bingoNumberList.RemoveAt(randomIndex);

Though that’s not that important.

The way you have it is how I wrote it originally, but it was outputting the index and not the value at that index. That’s why I was trying it this way.

I will go back and try again. Thank you