Eeva
Eeva

Reputation: 99

Shuffle array in Unity

I want to shuffle the numbers in my array variable once, so I called my Shuffle method from Start().

I then attempt access the shuffled array from update, but I am unable to do so. How can I access it? Is there any other way to shuffle my array once, then use it forever?

private System.Random _random = new System.Random();
float sec;
float timecount;
float starttime;
void Start () {
    starttime = Time.time;
    int[] array = { 1, 2, 3, 4, 5, 6, 7, 8};
    Shuffle(array);
    foreach (int value in array)
    {
        Debug.Log(value);
    }
}

void Update () {
    //time
    timecount = Time.time - starttime;
    sec = (timecount % 60f);
    if (Mathf.Round(sec) == 3f) {
        //access shuffled array
        Debug.Log(array[3]);  <=====error here
    }
}

//for shuffle number from array
void Shuffle(int[] array){
    int p = array.Length;
    for (int n = p-1; n > 0 ; n--)
    {
        int r = _random.Next(1, n);
        int t = array[r];
        array[r] = array[n];
        array[n] = t;
    }
}

Upvotes: 2

Views: 12770

Answers (3)

Viccha
Viccha

Reputation: 1

There is still a problem with this algorithm. Imagine an array with values 0, 1, 2 The possible shuffles should be:

0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0

and the probability of each case should be the same. To achieve this modify int r = _random.Next(0, n+1); Because the max value of Random.Next is exclusive (see doc)

Upvotes: 0

Programmer
Programmer

Reputation: 125275

Move int[] array = { 1, 2, 3, 4, 5, 6, 7, 8}; outside the Start function.

private System.Random _random = new System.Random();
float sec;
float timecount;
float starttime;

int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };

void Start()
{
    starttime = Time.time;
    Shuffle(array);
    foreach (int value in array)
    {
        Debug.Log(value);
    }
}

void Update()
{
    //time
    timecount = Time.time - starttime;
    sec = (timecount % 60f);
    if (Mathf.Round(sec) == 3f)
    {
        //access shuffled array
        Debug.Log(array[3]);
    }
}

//for shuffle number from array
void Shuffle(int[] array)
{
    int p = array.Length;
    for (int n = p - 1; n > 0; n--)
    {
        int r = _random.Next(0, n);
        int t = array[r];
        array[r] = array[n];
        array[n] = t;
    }
}

EDIT: Not related to your question.

There is a bug in your Shuffle function. array[0] will always remain 1 and will never change. To fix this, replace int r = _random.Next(1, n); with int r = _random.Next(0, n); in the Shuffle function.

Upvotes: 2

James Hogle
James Hogle

Reputation: 3040

Currently, your array is declared within your Start() function. This means it can only be accessed from within the Start() function. If you want to be able to access the array from both Start() and Update() you need to increase its scope by declaring it globally. For example:

private System.Random _random = new System.Random();
float sec;
float timecount;
float starttime;

//declare array globally
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8};

void Start () 
{
  starttime = Time.time;
  Shuffle(array);
  foreach (int value in array)
  {
      Debug.Log(value);
  }
}

void Update () 
{
    //now you can access array here, because it is declared globally
}

Additionally, have a look at this MSDN article about scope in C#.

Upvotes: 2

Related Questions