AS3 Object shuffle or randomize

After I published my AS3 Vector shuffle or randomize post, Philip Bulley commented: “…I tried casting a Vector.int to Vector.*, but the vector becomes null within the shuffle method”. I never had to randomize a Vector.<int> but when I tried I discovered Philip was right, the result was null.

I solved this problem by changing my shuffleVector function into a more generic shuffleObject function. It solves all casting problems and you can use the shuffleObject function to randomize Objects, Array and Vectors. So if you want to randomize or shuffle an Object, Array or Vector, please use this function below instead of my previous shuffleVector function.

/**
 * Shuffles object with Fisher-Yates shuffle algorithm using Math.random
 * @param obj
 * example code to shuffle a vector: ObjectUtils.shuffleObject(myVector);
 */
public static function shuffleObject(obj:Object):void{
	var i:int = obj.length;
	while (i > 0) {
		var j:int = Math.floor(Math.random() * i);
		i--;
		var temp:* = obj[i];
		obj[i] = obj[j];
		obj[j] = temp;
	}				
}

At Gynzy we often use com.gskinner.utils.Rndm class because it generates random numbers based on a seed number. Necessary if you want to reproduce a random output.

/**
 * Shuffles object with Fisher-Yates shuffle algorithm
 * using com.gskinner.utils.Rndm class
 * @param obj
 * example code to shuffle a vector: ObjectUtils.shuffleObject(myVector);
 */
public static function shuffleObjectRndm(obj:Object):void{
	var i:int = obj.length;
	while (i > 0) {
		var j:int = Rndm.integer(0, i);
		i--;
		var temp:* = obj[i];
		obj[i] = obj[j];
		obj[j] = temp;
	}				
}

I really appreciate the Fisher-Yates shuffle algorithm, but I had to read this article to fully understand why it’s superior to a naive shuffle algorithm.

2 thoughts on “AS3 Object shuffle or randomize

  1. Alistair

    Thanks for an interesting blog post. I was just looking into the Fisher-Yates algorithm myself.

    I tried running your function multiple times over the array [1,2,3] and it’s displaying a bias towards certain permutations. Here is a sample of the number of each permutation I got over 100000 iterations:

    [123] 14846
    [132] 18297
    [213] 18461
    [231] 15008
    [312] 18554
    [321] 14834

    These biased values seem consistent with the naive implementation described here: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

    This code seems to work better:

    var i:int = obj.length;
    while (i > 0) {
    var j:int = Math.random() * i;
    var temp:* = obj[–i];
    obj[i] = obj[j];
    obj[j] = temp;
    }

    Rather than taking a random value from the length of the list, you take a random value from the iterator which is decremeted each time the while loop is executed. This means that every time you are picking a random item from a smaller and smaller pool of items. I hope that makes sense!

    Reply
  2. Arie Post author

    Hi Alistair, thank you for noticing the biased values my function produces. You’re complete right, I tested both functions and your code definitely gives better, unbiased results.

    I forgot that the range of items you randomly pick from are the selected item itself and all items that precede it. See this blogpost for a visual explanation: http://www.kirupa.com/flash/shuffling_array.htm

    I just updated my code.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *