[AS3] Array Randomization (SOLVED)

18 posts

Flag Post

I have an array of 52 numbers that represent the cards of a deck.

 
private var fullDeckArray:Array = [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13];

I am looking for a method to randomize there positions as if to shuffle the deck, without the use/creation of another array. If anyone knows how to do this is would help a lot. However if another array MUST be created then I would appreciate if you should explain/show the method.

Thank you very much!

 
Flag Post

No need to create another array, you could make a custom sort method and return a random order.

E: Also, you should use a Vector… it’s way faster.
Then just do:
private function random(a:int,b:int):int{return(((Math.random()*3)>>0)-1);}
fullDeckArray.sort(random);

 
Flag Post

Fisher-Yates Shuffle – Very easy to understand, simple, and effective

 
Flag Post

Senekiss93 – I tried using you function like so

I have a function that calls


trace(fullDeckArray)
//outputs 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13
fullDeckArray.sort(random);
trace(fullDeckArray)
//outputs The same array but with only 2 swapped numbers.

And this is your function


private function random(a:int,b:int):int
{
return Math.random() * 3 >> 0 – 1;
}

How would I implement it?

Also BobTheCoolGuy thank you for your reply but that link does not lead to simple answers. Not ones I can understand at least. :/

 
Flag Post

You have to place the parentheses as I did. The compiler is picky when dealing with bitwise operators.

 
Flag Post

Example:

for(var k:int = fullDeckArray.length-1; k>=1; --k)
{
      var j:int = Math.random()*(k+1);
      var temp:int = fullDeckArray[k];
      fullDeckArray[k]=fullDeckArray[j];
      fullDeckArray[j]=temp;
}
 
Flag Post

Oh wow, well yes that works, thank you very much. However it kind of sucks that flash auto format formats it like how I had it posted.

Thanks again.

 
Flag Post

Something like this:


private function fisher(a:Array):void{
			var r:int,i:int=a.length-1;
			for(;i>0;--i){
				r=Math.random()*i+1;
				a[i]^=a[r];
				a[r]^=a[i];
				a[i]^=a[r];
			}
}

Also, just ran a test with 1 mil elements arrays and got this:
Sort: 8718
Fisher: 529

For your example, it wouldn’t matter. 52 elements are sorted in 1 ms.

E: Ninja’d?

E2:

It seems somethign was using CPU while I ran that test as I just ran three more and got faster speeds:

Sort: 7177
Fisher: 478
Sort: 7024
Fisher: 474
Sort: 7165
Fisher: 477

E:3
Results using vectors:

Sort: 7227 / 7240 / 7358
Fisher: 380 / 380 / 379
FisherVar: 309 / 313 / 309

Sorting a vector is slower than sorting an array? :|
FisherVar uses a temporary variable instead of XOR (thanks to Skyboy).
for(;i>0;--i){r=Math.random()*i+1;t=a[i];a[i]=a[r];a[r]=t;}

 
Flag Post

XD this is really not a big deal for this project but maybe those test will help me out sometime in the future were that kind of optimization is critical.

Thanks again for the test however this still breaks flash’s auto format.

Whenever I press the button it puts a semi-colon after the “for(;i>0;—i){”

Which makes


for(;i>0;—i){;

And screws up the whole format structure :(

 
Flag Post

Yeah, for such a small number of elements you can pretty much do anything and get away with it, but it’s always good to get used to do things in the best possible way.

Also, just added more tests.

E: About the auto formatting, I’m not used to Flash Pro’s options, but I guess there’s a way to turn that off.
You could also use FD or Notepad++ or anything but Flash for editing your code.

 
Flag Post

E: Ninja’d?

by 5 mins :D

FisherVar uses a temporary variable instead of XOR (thanks to Skyboy).

Three reasons I did it that way – it normally is faster (also less array lookups), it’s clearer, and if you’re not using ints, it easier to switch around.

for(;i>0;--i){r=Math.random()*i+1;t=a[i];a[i]=a[r];a[r]=t;}


Check the Math.random() statement – you’ll never get the 0 index, so it won’t shuffle quite right.
 
Flag Post
Originally posted by BobTheCoolGuy:

E: Ninja’d?

by 5 mins :D

Yes, while setting up the tests and running them?

for(;i>0;--i){r=Math.random()*i+1;t=a[i];a[i]=a[r];a[r]=t;}

Check the Math.random() statement – you’ll never get the 0 index, so it won’t shuffle quite right.

What’s the point of reaching 0?
Math.random()==0 That results in the element shuffling with itself.

 
Flag Post
Originally posted by Senekis93:
Originally posted by BobTheCoolGuy:

E: Ninja’d?

by 5 mins :D

Yes, while setting up the tests and running them?

for(;i>0;--i){r=Math.random()*i+1;t=a[i];a[i]=a[r];a[r]=t;}

Check the Math.random() statement – you’ll never get the 0 index, so it won’t shuffle quite right.

What’s the point of reaching 0?
Math.random()==0 That results in the element shuffling with itself.

You start with the last element and go down to element one. If you never get a 0 index, the first item will never be able to move.

 
Flag Post

You have to trust the chances that r will be 0 at some point during the process. As I said, i=0 is useless:

//i = 0;
r=Math.random()*(0+1); // r == 0
t=a[0];
a[0]=a[0];
a[0]=t;
// a[0] stays the same.

 
Flag Post
Originally posted by Senekis93:

You have to trust the chances that r will be 0 at some point during the process. As I said, i=0 is useless:

//i = 0;
r=Math.random()*(0+1); // r == 0
t=a[0];
a[0]=a[0];
a[0]=t;
// a[0] stays the same.

Correct – I was just saying that your algorithm is missing the parenthesis that would let that ever happen – you add 1 after multiplying.

 
Flag Post

Originally posted by Senekis93:

You have to trust the chances that r will be 0 at some point during the process. As I said, i=0 is useless:

// i = 0;
r=Math.random()*(0+1); // r == 0
t=a[0];
a[0]=a[0];
a[0]=t;

// a[0] stays the same.

you don’t use parens. you add one to the result of multiplying i by a random number; in no case will r be 0. it will never be less than 1. the first element is never shuffled.

remove the +1, and you solve the issue.

 
Flag Post
Originally posted by skyboy:

Originally posted by Senekis93:

You have to trust the chances that r will be 0 at some point during the process. As I said, i=0 is useless:

// i = 0;
r=Math.random()*(0+1); // r == 0
t=a[0];
a[0]=a[0];
a[0]=t;

// a[0] stays the same.

you don’t use parens. you add one to the result of multiplying i by a random number; in no case will r be 0. it will never be less than 1. the first element is never shuffled.

remove the +1, and you solve the issue.

You do need the +1 also, or else the last element will never be able to stay in its own position

 
Flag Post

Yeah, the +1 was the issue. Thanks.