Как исправить «исключение индекса вне диапазона» при достижении последнего индекса массива - PullRequest
1 голос
/ 01 октября 2019

У меня есть скрипт, который я использую для выбора случайного элемента из массива с взвешенным шансом, и по большей части он работает хорошо. Проблема возникает, когда индекс достигает последнего элемента в массиве.

Вот мой код:

string[] grades = { "D", "C", "B", "A", "S" };
int[] weights = { 80, 140, 170, 180, 181 };
// 80, 60, 30, 10, 1

int iterations = 100;

void Update() {
    if (iterations > 0) {
        string genGrade = grades[WeightedChance(weights)];
        print("Chance: " + chance + ", Grade: " + genGrade);
        iterations--;
    }
}

int WeightedChance(int[] weights) {
    float weightSum = weights[weights.Length - 1];

    float chance = Random.Range(0f, weightSum);

    for (int i = 0; i < weights.Length - 1; i++) {
        if (chance <= weights[i]) {
            return i;
        }
    }
    return -1;
}

Из того, что я понимаю, когда i добирается до последнего элемента в массивекажется, что он пропускается, а затем запускается return -1, давая мне «IndexOutOfRangeException». Кажется, я не могу понять, почему именно это происходит. chance генерирует число от 0f до weightSum (или 181 в данном случае), оба включаются, поскольку они являются числами с плавающей точкой. После этого я проверяю каждый элемент в weights и проверяю, меньше или равно число, сгенерированное chance, каждому из них. Если все это работает так, как я думаю, то должно быть всегда возможно выбрать один из весов, но что-то идет не так, когда i достигает 4 (по крайней мере, это то, что я предполагаю). Я новичок во всем этом, поэтому я прошу прощения, если я пропустил что-то важное или мой код не отформатирован правильно.

Ответы [ 4 ]

1 голос
/ 01 октября 2019

Ошибка возникает в этой части:

 string genGrade = grades[WeightedChance(weights)];

Когда WeightedChance возвращает -1, вы получаете grades[-1], что, конечно, выходит за пределы

1 голос
/ 01 октября 2019

Эта строка неверна:

for (int i = 0; i < weights.Length - 1; i++) {

Вы должны идти до "weights.Length", а не "weights.Length - 1".

Вы не достигли последнего элемента.

0 голосов
/ 01 октября 2019

Я думаю, что вы неправильно поняли оператор < в цикле for, это означает, что значение «строго меньше», чем то, что вы сравниваете, что означает, что равенство не удовлетворяет этому условию.

В вашем случае вы переходите на weights.Length -1, который, как вы говорите, равен 4, но условие в цикле for гласит, что он должен работать до тех пор, пока i не станет "строго меньше", чем 4, поэтому i достигнет максимального значения 3, без проверки последнего элемента 181.

Для решения этой проблемы у вас есть 2 решения:

  • Измените оператор на <= (меньше или равно), что охватывает случай i=4
  • Запустите цикл for до Weight.Length без вычитаний (как уже предлагалось в других ответах)
0 голосов
/ 01 октября 2019

Попробуйте вот так

void Update() {
if (iterations > 0) {
  int x= WeightedChance(weights);
   if(x>=0){
    string genGrade = grades[x];
    print("Chance: " + chance + ", Grade: " + genGrade);
    iterations--;
   }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...