# [AS3] Array Randomization (SOLVED)

18 posts

 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! 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);` Fisher-Yates Shuffle – Very easy to understand, simple, and effective 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. :/ You have to place the parentheses as I did. The compiler is picky when dealing with bitwise operators. 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; }``` 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. 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;}` 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 :( 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. 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. Originally posted by BobTheCoolGuy: E: Ninja’d? by 5 mins :D Yes, while setting up the tests and running them? `for(;i&gt;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. 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&amp;gt;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. 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. ``` 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. 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. 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 Yeah, the +1 was the issue. Thanks.