Unity3D – Game Engine – Shuffle an Array – Fisher–Yates shuffle
In game programming shuffle (mischiare) an array is useful to shuffle cards, bonus locations and so on…
The most used is the Fisher–Yates shuffle (named after Ronald Fisher and Frank Yates), also known as the Knuth shuffle (after Donald Knuth), is an algorithm for generating a random permutation of a finite set—in plain terms, for randomly shuffling the set.
The general rule is:
To shuffle an array a of n elements (indices 0..n-1):
for i from n – 1 downto 1 do
j ? random integer with 0 = j = i
exchange a[j] and a[i]
Let’s go on!
Create a scene with a Main Camera and attach the script “ArrayShuffle.js”:
#pragma strict // Array Start var uniqueCard = new Array(); uniqueCard [0] = "Card0"; // Notice: the first value is 0 uniqueCard [1] = "Card1"; uniqueCard [2] = "Card2"; uniqueCard [3] = "Card3"; uniqueCard [4] = "Card4"; uniqueCard [5] = "Card5"; uniqueCard [6] = "Card6"; uniqueCard [7] = "Card7"; uniqueCard [8] = "Card8"; uniqueCard [9] = "Card9"; // Array End var usedCardLocation; // variabile per Shuffle() -> rimescolare l'Array function Start () { } function Update () { } function OnGUI () { // print in console the array content if (GUI.Button (Rect (10,10,150,100), "Print the Array!")) { PrintArray(); } // shuffle the array (rimescola l'array) if (GUI.Button (Rect (300,10,150,100), "Shuffle the Array!")) { Debug.Log("Shuffle"); Shuffle(); } } function Shuffle(){ // Randomize the order of index... // vediamo come funziona al primo ciclo del loop... // genera un loop pari alla lunghezza dell'array-1 perchè l'array ha l'indice che parte da zero for ( var c=0; c <= uniqueCard.length-1; c++) // 1. per c = 0 { var thisCard = Random.Range (c, uniqueCard.length); // 2. ad esempio thisCard=3 (crea un valore random compreso all'interno dell'indice dell'array) usedCardLocation = uniqueCard ; // 3. usedCardLocation = uniqueCard [0] uniqueCard = uniqueCard [thisCard]; // 4. uniqueCard [0] = uniqueCard [3] uniqueCard [thisCard] = usedCardLocation; // 5. uniqueCard [3] = usedCardLocation } // 6. riprendo dal punto 3. // 3. uniqueCard [3] = uniqueCard [1] (perchè c++ ha incrementato c di 1 unità) }// END Shuffle // si ripete per tutta la lunghezza dell'array... function PrintArray(){ // not elegant but easy to understand... Debug.Log(uniqueCard [0]); Debug.Log(uniqueCard [1]); Debug.Log(uniqueCard [2]); Debug.Log(uniqueCard [3]); Debug.Log(uniqueCard [4]); Debug.Log(uniqueCard [5]); Debug.Log(uniqueCard [6]); Debug.Log(uniqueCard [7]); Debug.Log(uniqueCard [8]); Debug.Log(uniqueCard [9]); }
Play, press ‘Print the Array!’ and watch Inspector, press ‘Shuffle the Array’, press ‘Print the Array!’ and watch Inspector.
For italian people, come funziona?
function Shuffle(){ // Randomize the order of index... // vediamo come funziona al primo ciclo del loop... // genera un loop pari alla lunghezza dell'array-1 perchè l'array ha l'indice che parte da zero for ( var c=0; c <= uniqueCard.length-1; c++) // 1. per c = 0 { var thisCard = Random.Range (c, uniqueCard.length); // 2. ad esempio thisCard=3 (crea un valore random compreso all'interno dell'indice dell'array) usedCardLocation = uniqueCard ; // 3. usedCardLocation = uniqueCard [0] uniqueCard = uniqueCard [thisCard]; // 4. uniqueCard [0] = uniqueCard [3] uniqueCard [thisCard] = usedCardLocation; // 5. uniqueCard [3] = usedCardLocation } // 6. riprendo dal punto 3. // 3b. uniqueCard [3] = uniqueCard [1] (perchè c++ ha incrementato c di 1 unità) }// END Shuffle
Tutto si basa sulla permutazione tra i vari valori dell’array, nei commenti del codice al punto:
– 4. uniqueCard [0] = uniqueCard [3]
– al punto 3b uniqueCard [3] = uniqueCard [1]