Hi I need a way for getting random colour from an Array of hexadecimal values:
Code:var arr:Array = [0xFF0000,0xFF6600,0xFFFF00,0x0066FF,0x00FF00];
var colour:Number = //Random Value from arr
Any ideas?
Printable View
Hi I need a way for getting random colour from an Array of hexadecimal values:
Code:var arr:Array = [0xFF0000,0xFF6600,0xFFFF00,0x0066FF,0x00FF00];
var colour:Number = //Random Value from arr
Any ideas?
PHP Code:
var color:uint = arr[Math.round(Math.random()*arr.length-1)];
Thanks
@ MyFriendIsATaco: your code is almost correct, but there's a tiny problem with it... By using Math.round you might end up with a situation when instead of getting a random index from 0 to the length - 1 you'll get an index of -1 and it will return undefined...
A better solution would be to use Math.ceil instead of random:
PHP Code:
var arr:Array = [0xFF0000, 0xFF6600, 0xFFFF00, 0x0066FF, 0x00FF00];
var randIndex:Number = Math.ceil(Math.random() * arr.length - 1);
var randColor:uint = arr[randIndex];
OR, I should have just used another set of parenthesis (Damn order of operations):Math.ceil() is going to cause the results to NEVER be 0. It'll essentially return 1- arr.lengthPHP Code:
var color:uint = arr[Math.round(Math.random()*(arr.length-1))];
Why would ceil screw the randomness ? Please explain...
EDIT: it's essentially the same thing as using Round ( in your last post ) just that it has a slightly larger chance to hit a bigger index value than a lower one ( but that chance isn't really a significant impact ). I don't see any "scientific" reason why it would screw up the randomness...
Hmm, you're right. But in a different way than I expected. Take a look:Using Math.round() clumps the results in the middle. There are half as many 0s and the max as there should be:PHP Code:
var results:Array = new Array(10);
for(var i:int=0; i<10; i++) results[i] = 0;
for(i=0; i<30000; i++) results[Math.ceil(Math.random()*10)-1]++;
trace(results); //3059,3025,3068,2947,3076,2904,2955,3000,3010,2956
Not quite sure why it's like that.PHP Code:
var results:Array = new Array(10);
for(var i:int=0; i<10; i++) results[i] = 0;
for(i=0; i<30000; i++) results[Math.round(Math.random()*9)]++;
trace(results); //1607,3235,3466,3342,3258,3354,3326,3337,3330,1745
So I guess the best random solution to your problem would be:Notice the -1 outside the parenthesis. If it was inside, your results will always be 1 too high. 0 would never be an answer.PHP Code:
var color:uint = arr[Math.ceil(Math.random()*arr.length)-1];
Any idea why Math.ceil() provides a better deviation as opposed to Math.round()?
You got me confused a bit... Why did you use dual random instead of round and random in the second situation ?
What were you trying to prove / test there ?
Yes. :) Too early in the morning.
I edited. It was an error from copying/pasting.Quote:
Originally Posted by fx.barrett
I don't have a scientific explanation for this... but it might have something to do with possibility. We should take a look at the Math class an see how random works ( because random ain't really random, but it's just a "mathematical illusion" ) because it might provide the answer we are looking for. Maybe it's because of the algorithm that produces that "random value", it might favor ceil but don't forget that we didn't test floor...Quote:
Any idea why Math.ceil() provides a better deviation as opposed to Math.round()?
Or, it may have been just blind luck...
Floor produces some even results as well.PHP Code:
var results:Array = new Array(10);
for(var i:int=0; i<10; i++) results[i] = 0;
for(i=0; i<30000; i++) results[Math.floor(Math.random()*10)]++;
trace(results); //2993,2999,2889,2950,3069,3081,3032,2979,2985,3023
I'm not buying that. :) I ran it several times to make sure, and every time, the 0 and 9 index fell right in line with ~1600. Making it just about right in the middle of where it should be, 3000.Quote:
Originally Posted by fk.barrett
Even out of 1,000,000, the results are odd.The 0 and 9 are approx equal at ~5.6% of the results. And everything else gets an ~11.1% instead of an equal 10% spread. Something is NOT coincidental here.PHP Code:
var results:Array = new Array(10);
for(var i:int=0; i<10; i++) results[i] = 0;
//done in segments to avoid Flash from freaking out
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
for(i=0; i<50000; i++) results[Math.round(Math.random()*9)]++;
trace(results); //55586,111564,111203,110724,111023,110699,111138,111330,111049,55684
var percentages:Array = new Array(10);
for(i=0; i<10; i++) percentages[i] = Math.round((results[i]/1000000)*10000)/100 + "%";
trace(percentages); //5.56%,11.16%,11.12%,11.07%,11.1%,11.07%,11.11%,11.13%,11.1%,5.57%
Nothing is perfect :) Nor is ActionScript...
Yeah, well, Math.floor produces a nice even spectrum. And for the real nit-picky, probably a bit quicker to process than the Math.ceil method and Math.round method since there is no subtraction of 1 involved. No, I don't feel like running tests on that right now.
So, in the end unrealhacker12, I guess here is what the nerds have concluded::yikes:PHP Code:
var color:uint = arr[Math.floor(Math.random()*arr.length)];
If optimization is important to you, you'd be far better off saving the array length to a constant somewhere and using a hard-cast to int instead of the static call to Math.floor():
PHP Code:
const ARR_LEN:int = arr.length;
// ...
var c:uint = arr[int(Math.random() * ARR_LEN)];
Oops, completely forgot about just casting to int. :)
Thanks!
Uhh, really late reply... Sorry.
@ neznein9: yeah, that's a good way of doing it. An even faster would be this:
Bitwise operations will outperform everything else.PHP Code:
var arr:Array = [0xFF0000, 0xFF6600, 0xFFFF00, 0x0066FF, 0x00FF00];
var randIndex:Number = (Math.random() * arr.length - 1) >> 0;
var randColor:uint = arr[randIndex];
trace(randColor);
Holy crap - bit-shifting by zero is brilliant!! I have to go benchmark some stuff right away...