Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

IndexOutOfRange on a scoring script

Discussion in 'Scripting' started by Vini310, Apr 22, 2020.

  1. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    For a class at university, the professor gave us a scoring script that's basically this:
    Code (CSharp):
    1. public class Basico : MonoBehaviour
    2. {
    3.    
    4. void Start()
    5.     {
    6.     int i;
    7.     int[] lutador1 = new int[10];
    8.    
    9.     for (i = 0; i < 10; i++)
    10.     {
    11.         lutador1[i] = Random.Range(1, 100);
    12.         print("Lutador1[" + i + "] = " + lutador1[i]);
    13.     }
    14.    
    15.     int[] lutador2 = new int[10];
    16.     for (i = 0; i < 10; i++)
    17.     {
    18.         lutador2[i] = Random.Range(1, 100);
    19.         print("Lutador2[" + i + "] = " + lutador2[i]);
    20.     }
    Our goal is to make it so the game will tell us (i.e. print) which "lutador" has won in the end of int [10] (which goes from 0 through 10). I tried to do so by making this:
    Code (CSharp):
    1. if (lutador1[i] > lutador2[i])
    2.     {
    3.         print("Lutador1 venceu!");
    4.     }
    5.     if (lutador2 [i] > lutador1[i])
    6.     {
    7.         print("Lutador2 venceu!");
    8.     }
    And every time I playtest to see if the script is working, an IndexOutOfRange message appears (the numbers are still counted, but the text showing who won does not appear), according to Unity itself, the error is on the new code I added (with the if clauses). I still couldn't fix the problem.

    What's wrong with this script!?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,970
    If the second block of code is outside of the for() loops, the value of i will likely be 10.

    For loops it's best to use local variables so this isn't possible.

    Code (csharp):
    1. for(int i = 0; i < 10; i++)
    Obviously you would NOT in that case declare i at the top of your Start() method.

    ALSO: realize that lutador1 and lutador2 are local to Start() only, they are NOT class variables.
     
  3. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    Yes, the second block IS outside of the loops, but still inside the void Start.
    And if I don't declare i, the script won't run ("The name 'i' doeas not exist in the current context"), nad the same happens if I try to move the second block to the void Update.
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    As already mentioned, after your loops the value of 'i' is probably 10. In your second block of code, you are reusing i to access an index in your arrays, but a value of 10 will result in an index out of range error, since your arrays only have indexes from 0-9.

    If you're changing the value of 'i' before you run that second block of code, please show that part.

    It is unusual to declare the integer you use to run through your "for loop" outside of the declaration of the loop by the way.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,970
    Not only that, but it leads to precisely this error!

    OP: restating the problem, in the second block of code you posted, you are using i, and the value of i is now well beyond the acceptable range because your previous for() loops moved it there.

    When Uncle Joe and I are suggesting using a variable INSIDE the for() loop (as my code explicitly), that is explicitly to prevent you from using i OUTSIDE the loop, because if you do so it is stale and beyond the range and causes precisely the error you're seeing here. The reason you get a compiler error is because actually ARE using it when you should not be.

    In your original code, if you intend to dereference by i, make sure it is a value acceptable for your 10-element arrays, which means a value from 0 to 9, inclusive.
     
  6. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    I tried to change the position of the second block from Start to Update, but since this only worsened the error, I returned it to its original position.

    And the code, right now, looks like this:
    Code (CSharp):
    1. public class Basico : MonoBehaviour
    2. {
    3.  
    4. void Start()
    5.     {
    6.     int[] lutador1 = new int[10];
    7.  
    8.     for (int i = 0; i < 10; i++)
    9.     {
    10.         lutador1[i] = Random.Range(1, 100);
    11.         print("Lutador1[" + i + "] = " + lutador1[i]);
    12.     }
    13.  
    14.     int[] lutador2 = new int[10];
    15.     for (int i = 0; i < 10; i++)
    16.     {
    17.         lutador2[i] = Random.Range(1, 100);
    18.         print("Lutador2[" + i + "] = " + lutador2[i]);
    19.     }
    20.     if (lutador1[i] > lutador2[i])
    21.     {
    22.         print("Lutador1 venceu!");
    23.     }
    24.     if (lutador2 [i] > lutador1[i])
    25.     {
    26.         print("Lutador2 venceu!");
    27.     }
    28.  
    29. }
    I'm getting the "The name 'i' does not exist in the current context" error, this time coming from line 24 (line 20 here) (where the if clause starts). Guess the best option is to remove the "if", or deactivate them for now while I try to prevent the i from being outside the loop.
     
  7. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    What does this mean exactly? Are you checking to see which list has the highest value? Or which list's final value is the highest (which is kind of what your code seems to be trying to do).

    Try to understand exactly what the error message means, and why you are getting it, instead of just trying to tinker with the code until the error message disappears.
     
  8. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    Which one has the highest value. Basically, pick all the values from both sides and sum them to see which "list" won. (hence the if lutador1 > lutador2 thing).
     
  9. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    Then you need to iterate through each list and compare each element. In order to do this, you will need another for loop. Try putting your additional code in another for loop (like the ones above), and go from there.
     
  10. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    - When I transfer the second block to the void Update, a message saying that "lutador1", and "lutador2" (without the quotation marks) does not exist in the current context. The same happened when I erased int i (inside the void Start, before anything else).
    - If I try to put the second block inside the "for" loop, it will display a message saying that the variable "lutador2" cannot be used before it's declared. And, just to clarify, I made TWO if clauses: one in case lutador1 > lutador2, and other in case lutador2 > lutador1, and I added each one in their respective "for" loop.
    And, while typing this, I had an idea:

    Code (CSharp):
    1. public class Basico : MonoBehaviour
    2. {
    3.  
    4. void Start()
    5.     {
    6.     int[] lutador1 = new int[10];
    7.  
    8.     for (int i = 0; i < 10; i++)
    9.     {
    10.         lutador1[i] = Random.Range(1, 100);
    11.         print("Lutador1[" + i + "] = " + lutador1[i]);
    12.         //if (lutador1[i] > lutador2[i])
    13.         //{
    14.             //print("Lutador1 venceu!");
    15.         //}  
    16.     }
    17.  
    18.     int[] lutador2 = new int[10];
    19.     for (int i = 0; i < 10; i++)
    20.     {
    21.         lutador2[i] = Random.Range(1, 100);
    22.         print("Lutador2[" + i + "] = " + lutador2[i]);
    23.         if (lutador1[i] > lutador2[i])
    24.         {
    25.             print("Lutador1 venceu!");
    26.         }  
    27.         if (lutador2[i] > lutador1[i])
    28.         {
    29.             print("Lutador2 venceu!");
    30.         }
    31.     }
    32.     //if (lutador1[i] > lutador2[i])
    33.     //{
    34.         //print("Lutador1 venceu!");
    35.     //}
    36.     //if (lutador2 [i] > lutador1[i])
    37.     //{
    38.         //print("Lutador2 venceu!");
    39.     //}
    40.  
    41. }
    42.  
    43. // Update is called once per frame
    44.     void Update()
    45.     {
    46.         //if (lutador1[i] > lutador2[i])
    47.     //{
    48.         //print("Lutador1 venceu!");
    49.     //}
    50.     //if (lutador2 [i] > lutador1[i])
    51.     //{
    52.         //print("Lutador2 venceu!");
    53.     //}
    54.     }
    EDIT: No error messages, but it's not working as expected. The message was only supposed to appear AFTER BOTH OF THEM had ended scoring, but instead, it's appearing after one of them ended and shortly after the other started (basically, they both are winning).
     
  11. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    You don't need to put anything at all in Update to do this.

    If you want to check which list has the largest score then you need to:

    1. Get the largest element of lutador1
    2. Get the largest element of lutador2
    3. Compare these 2 values and see which is the greatest.

    Try solving these problems individually i.e. first work out how to get the largest element from an array, before printing which one has won.
     
  12. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    So, after searching for codes to find the highest value, I modified the script to this:
    Code (CSharp):
    1. void Start()
    2.     {
    3.     Debug.Log (MaxValue(int));
    4.     int[] lutador1 = new int[10];
    5.     for (int i = 0; i < 10; i++)
    6.     {
    7.         lutador1[i] = Random.Range(1, 100);
    8.         print("Lutador1[" + i + "] = " + lutador1[i]);
    9.         var max = lutador1[0]
    10.         if (lutador1[i] > max)
    11.         {
    12.             max = lutador1[i];
    13.         }
    14.     }
    15.  
    16.     int[] lutador2 = new int[10];
    17.     for (int i = 0; i < 10; i++)
    18.     {
    19.         lutador2[i] = Random.Range(1, 100);
    20.         print("Lutador2[" + i + "] = " + lutador2[i]);
    21.         if (lutador1[i] > lutador2[i])
    22.         {
    23.             print("Lutador1 venceu!");
    24.         }  
    25.         if (lutador2[i] > lutador1[i])
    26.         {
    27.             print("Lutador2 venceu!");
    28.         }
    29.     }
    30.  
    31.  
    32. }
    Result? Inavlid expression term "int" (courtesy of Debug.Log (MaxValue(int)))
     
  13. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    That is because that line makes no sense at all. Where did you get this line of code from?

    Your closer, but there are still a bunch of odd things going on in that code.

    This defines the max variable within the for loop, so it will not be accessible outside of it.

    On top of that, each iteration, it just assigns the first value of the array to it. So your code

    Only checks if the current value is greater than the first value (and not the current max value, which you want). Then it assigns the current value to max, which is forgotten about anyway next iteration.
     
    Last edited: Apr 23, 2020
    matkoniecz likes this.
  14. Vini310

    Vini310

    Joined:
    Apr 22, 2020
    Posts:
    23
    Sorry for the late response, but the problem is solved now. I spoke to the professor during class and he showed us what the problem was:
    The idea was to pick the total number of each value (lutador1 and lutador2) and see which one has the highest value, but in the way I was doing it, the script was just picking a random number OR comparing EACH NUMBER individually (rather than comparing the total). Two new ints, called "total_Round_Lutador1" and "total_Round_Lutador2" had to be created to store the maximum value.
    Also, everything is better placed now:

    Code (CSharp):
    1. public class Basico : MonoBehaviour
    2. {
    3.     int i;
    4. void Start()
    5. {
    6.     int[] lutador1 = new int[10];
    7.     int[] lutador2 = new int[10];
    8.     int[] vencedor = new int[10];
    9.     int total_Round_Lutador1 = 0, total_Round_Lutador2 = 0;
    10.    
    11.     for (i = 1; i < 10; i++)
    12.     {
    13.         lutador1[i] = Random.Range(1, 100);
    14.         lutador2[i] = Random.Range(1, 100);
    15.     }
    16.     for (i = 1; i < 10; i++)
    17.     {
    18.         if (lutador1[i] > lutador2[i])
    19.         {
    20.             vencedor[i] = i;
    21.         }
    22.         else
    23.         {
    24.             if (lutador1 [i] < lutador2[i])
    25.             {
    26.                 vencedor[i] = 2;
    27.             }
    28.             else
    29.             {
    30.                 vencedor[i] = 0;
    31.             }
    32.         }
    33.     }  
    34.    
    35.     for (i= 1; i < 10; i++)
    36.     {
    37.         if (vencedor[i] == 1)
    38.         {
    39.             total_Round_Lutador1++;
    40.         }
    41.         if (vencedor[i] == 2)
    42.         {
    43.             total_Round_Lutador2++;
    44.         }  
    45.     }
    46.    
    47.     for (i=1; i < 10; i++)
    48.     {
    49.         print("Round " + (i) + "| Lutador 1 (" + lutador1[i] + ") x Lutador 2 (" + lutador2[i] + ")");
    50.     }
    51.     print("O Lutador 1 venceu " + total_Round_Lutador1 + " Rounds");
    52.     print("O Lutador 2 venceu " + total_Round_Lutador2 + " Rounds");
    53.    
    54.     if (total_Round_Lutador1 > total_Round_Lutador2)
    55.     {
    56.         print("Vencedor da luta é Lutador 1");
    57.     }
    58.     else
    59.     {
    60.         if (total_Round_Lutador1 < total_Round_Lutador2)
    61.         {
    62.             print("Vencedor da luta é o Lutador 2");
    63.         }
    64.         else
    65.         {
    66.             print("Empate técnico!");
    67.         }
    68.     }
    69. }
    70. }
    71.  
    The "Debug.Log (MaxValue(int))" was an attempt to pick something I saw in other scripts around the Internet and convert to my script.