Come si randomizza un array usando actionscript 3?array casuale as3 - array randomize - actionscript 3
risposta
c'è una versione corta utilizzando la funzione Array.sort():
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize (a : *, b : *) : int {
return (Math.random() > .5) ? 1 : -1;
}
trace(arr.sort(randomize));
Se non si ottiene "abbastanza" casualità è possibile ordinare due volte :)
EDIT - spiegazione riga per riga:
Per Array
metodo di classe sort()
è possibile passare non solo opzioni di ordinamento come Array.CASEINSENSITIVE, Array.DESCENDING
e così via ma anche il proprio riferimento alla funzione di confronto personalizzato (un callback) che accetta due parametri (due elementi dalla matrice per confrontare). Dalla documentazione AS3:
Una funzione di confronto dovrebbe richiedere due argomenti da confrontare. Dati gli elementi A e B, il risultato di compareFunction può avere un valore negativo, 0 o positivo:
- Un valore di ritorno negativo specifica che A viene visualizzato prima di B nella sequenza ordinata.
- Un valore di ritorno pari a 0 specifica che A e B hanno lo stesso ordine.
- Un valore di ritorno positivo specifica che A viene visualizzato dopo B nella sequenza ordinata.
Nota: confronta i parametri di funzione potrebbero essere digitato (se l'array viene digitata) e avere qualsiasi nome che si desidera ad es .:
function compareElements (elementA : SomeClass, elementB : SomeClass) : int;
Questo metodo è molto utile quando si ha bisogno di ordinare serie elementi dalle loro proprietà speciali. Nel caso di randomizzazione compareFunction
restituisce in modo casuale -1, 0
o 1
e rende gli elementi di matrice per cambiare posizione (indici). Ho trovato che una migliore randomizzazione (nel mio parere soggettivo e matematicamente non verificato) è quando il metodo restituisce solo -1
e 1
. Tieni presente inoltre la funzione di ordinamento con la funzione di confronto personalizzata doesn't compare elements sequentially, pertanto in alcuni casi speciali i risultati di randomizzazione potrebbero essere diversi da quelli che potresti aspettarti.
Ho trovato questo molto utile. Spero possa aiutarti anche tu.
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
C'è un modo migliore che vi permetterà anche di casuale l'array in posizione, se avete bisogno di questo, e non farà si crea più di una singola copia della matrice originale.
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
Avevo un requisito alternativo in cui volevo inserire casualmente molti array di sorgenti in una matrice di destinazione casualmente. Come Rytis, sono un grande fan delle funzioni forEach, map e sort su Arrays.
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
ecco una funzione più semplice. Funziona anche su array multidimensionali
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
Se è necessario spostare l'array (i propri elementi non possono essere ripetuti).È possibile utilizzare questa funzione:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
Usage:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
è così che ho randomizzare la mia serie di 36 carte per un gioco di memoria
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}
scegliere stringa casuale dalla gamma
function keyGenerator(len:Number):String
{
function randomRange(minNum:Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var key = "";
for (var i=0; i<len; i++)
{
key += hexArray[randomRange(0,hexArray.length-1)];
}
return key;
}
utilizzo:
trace(keyGenerator(16));
Penso '(Math.random() <.5)? -1: 1' è migliore. – Florent
Concordato, più efficiente e non c'è bisogno di arrotondare – BadFeelingAboutThis
Questo è abbastanza FANTASTICO. Puoi abbattere le linee e spiegare cosa stanno facendo? Come quello che è (a: *, b: *) e il tipo ecc. –