- Home /
Why this fuction make the game to pick numbers which is already removed from list through Random.Range?
void AvailableMoves()
{
for (int i = 0; i < buttonList.Length; i++)
{
if (buttonList[i].text == "")
{
availableList.Add(i);
}
else
{
availableList.Remove(i);
}
availableMin = availableList.Min();
availableMax = availableList.Max();
availableRandom = availableList[Random.Range(availableMin, availableMax)];
}
}
It's a Tic-Tac-Toe game with AI.
When it's its turn, before it plays, this function will check every button if it's unoccupied then it will be added in a list of available buttons. If not, it will be removed.
But AI can still pick buttons which is already removed.
Why? Thanks.
Answer by M-Elwy · Feb 19, 2021 at 11:27 PM
If you have only 2 unoccupied buttons (ex : 1 and 7), Min() will evaluate to 1, Max() will evaluate to 7, Random.Range(availableMin, availableMax) will return any number between 1 and 7, it may return 2,3,4,5 or 6 which are in range but are occupied.
The correct way is something like this:
void AvailableMoves()
{
// Resetting the list as .Clear() will clear values but keep the capacity of the list
availableList = new List<int>();
for (int i = 0; i < buttonList.Length; i++)
{
if (buttonList[i].text == "")
{
// Adding only unoccupied buttons
availableList.Add(i);
}
}
// Checking if the list was populated
if (availableList.Count > 0)
{
availableMin = 0;
availableMax = availableList.Count;
availableRandom = availableList[Random.Range(availableMin, availableMax)];
}
else
{
// No buttons available.
}
}
Edit: code correction
The problem is that availableMax keeps to increase size of list because there's not Clear() after using availableRandom.
But with your code, it works better but still not perfect because sometimes that makes AI to reuse the button which is already occupied..
the list gets reset first line in the function before we make any step
I think that I found the problem, look at the comment below. I will explain in there.
Also about reseting the list, no it seems not. If you know how, may you explain? Thanks!
Answer by Jerem0597 · Feb 19, 2021 at 11:58 PM
@unity_k5jZb8tvx_RtNA Thanks for your explanation but I tried with that like what you said:
private List<int> availableList = new List<int>();
private int availableMin = 0;
private int availableRandom;
void AvailableMoves()
{
for (int i = 0; i < buttonList.Length; i++)
{
if (buttonList[i].text == "")
{
availableList.Add(i);
}
if (availableList != null)
{
availableRandom = availableList[Random.Range(availableMin, availableList.Count)];
}
else
{
}
}
Then the console signals an error:
"ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection."
Original answerer was spot on with the random range part but checking if the list is null is not the right check to see if it has no elements in it.
Since it's set to an empty list in the first few lines it will never be null at this point. Here you can check whether availableList.Count > 0 to avoid that exception.
P.S. when you call Clear() on a list, the count does get reset to 0 too so if you need that extra millisecond, you can do this instead of creating a new list each time.
Remember to accept their answer if this solves your problem!
So I tried that:
void AvailableMoves()
{
for (int i = 0; i < buttonList.Length; i++)
{
if (buttonList[i].text == "")
{
availableList.Add(i);
}
if (availableList.Count > 0)
{
availableRandom = availableList[Random.Range(availableMin, availableList.Count)];
availableList.Clear();
}
}
Debug.Log("List.Count: " + availableList.Count);
}
That makes AI to choose the largest value [i] of available buttons in every turn.
So I put Debug to check what is happening in availableList.Count. It logs 0 so Random.Range will pick a value between 0 and 0 then I don't know why it keeps to pick the largest like in the bottom right corner then bottom middle, then left, etc. It's strange.
And yes, I will accept his answer if it works but actually it still doesn't.
It returns 0 as you just cleared the list in the previous line.
Your answer