- Home /
Randomly Pick Between Two Numbers
Is it possible to randomly pick between numbers? Im not looking for a range between them. I simply want to randomly pick between two floating integers, like if I want to have it choose to pick the number 1 or the number 5. Is this possible?
Answer by Fattie · Feb 07, 2013 at 10:21 AM
Here's how you do that:
make an array (or perhaps list) of the things in question
var choices:int[] = [ 1, 5, 78, 42, 3 ];
now get the length of the array
var howManyThings:int = choices.length;
now get a random number in that amount
don't forget you want an index, not an ordinal, since it's an array.
var myRandomIndex:int;
myRandomIndex = Random.Range( 0, howManyThings );
(if you are not very familiar with Random.Range and the range it gives, read the documentation carefully.)
In our example this will be one of the numbers 0 1 2 3 4. (note - not 5, there is no 5 in the array)
finally get the result, a random item from your array
var result:int;
result = choices[ myRandomIndex ];
you can do this with ints, Strings or anything. the array "choices" could be Strings, floats or whatever you want.
it is extremely common in games to see things like ..
var choices:String[] = [ "Zombie", "Zombie", "Zombie", "Zombie", "Asteroid" ];
you can see that it will USUALLY be a Zombie, but occasionally an Asteroid. (You'd likely use an "Enum" here, learn about those later.)
In your example you'd simply have two items, var choices:int[] = [ 1, 29 ];
In normal programming languages you'd make a little extension something like choices.pickOne(),
and/or you'd make a little utility function pickOneOfThese("Zombie", "Zombie", "Zombie", "Zombie", "Asteroid" );
this sort of thing is used constantly everywhere, in game programming. You have to be extremely familiar with every possible aspect of choosing random things, numbers, times, etc etc, and all the common idiom for this sort of thing.
OK?
for this extensible approach that's not limited to just 2 numbers.
Nicely put. Thanks for putting in the effort. This worked perfectly.
hey @greg, no problem, since you're new to the site, please TIC$$anonymous$$ (round circle icon - tick in middle) any helpful answer, as only YOU can close out the question. thanks in advance and good luck
Answer by Wolfram · Feb 07, 2013 at 11:27 AM
If you really just want two numbers, simly use something like this:
if(Random.value<0.5f)
chosenNumber=42;
else
chosenNumber=4711;
Random.value resturns a value between 0 and 1, so by shifting 0.5 you could also modify the probability of the two numbers.
If you want a more flexible approach, see @Fattie's post.
you know it never occurred to me to use a float there, @Wolf. that is a fantastic idea. I have always just said Random.Range(0,2)==0 for a 50/50 chance.
obviously it's much better to use a float for many reasons, not least of which is that just as you say, one can easily modify the percentage. Thanks for that!
you know, in normal program$$anonymous$$g languages I always add new "control structures" via macros, such as ..
sometimes
{
}
usually
{
}
occasionallyDoThis
{
}
and so on .. it makes the code look really humorous :)
thanks again
Is there ever a chance of Random.Value == 0.5?
If so, the following may be more of an even split.
var val = Random.value;
if (val < 0.5f)
{
print("<");
}
else if (val > 0.5f)
{
print(">");
}
well 0.5 is not <0.5 so that will just result in 4711. since we are speaking of floats i guess this is as even as it goes
kinda late, but what if you try:
var val = (Random.value - 0.01f);
if (val <= 0.49f)
{
print("<");
}
else if (val >= 0.5f)
{
print(">");
}
if you like that you could use a ternary:
var val = (Random.value - 0.01f < 0.49) ? "<" : ">";
print("val");
or you could try Random.range to go from number 0 to 99
Umh, I don't think it is necessary to necro this ancient question that already has an accepted answer every few years... :-/
To answer the general question: There is no point in trying to make a "more even" split. The check for "<0.5" will split the interval into 0.0-0.499999970198 (=32bit floating point precision), and 0.5-1.0. So the asymmetry is less than 1e-7. Due to the fact that 1.0 is always included in the interval, there isn't a more even split, as the number of distinct floating point numbers that can be generated within that interval is odd. And if you're thinking of doing something like "if(val==0.5f) RecomputeAnotherNumberAndRepeat()", it's pretty much pointless and an unnecessary overhead. Also, you would be better advised to use double precision if such a $$anonymous$$or deviation is relevant to you.
Regarding your suggestions: The first one by shaneparsons has an unhandled case at 0.5 (which is a valid, precisely representable floating point number!), so you'll actually introduce a bug. The second one by XhryZed is even worse, as the first example will not only have an unhandled gap between 0.49...0.50, (i.e. in about 1%(!) of all cases it will NOT return a valid result!), and subtracting 0.01 is just pointless, as this merely shifts the returned range to (-0.01...0.99), so it's effectively the same as using the 0.5-test on the unmodified value.
Just stick with the 0.5 split, and be done with it. Even the Random.Range(0,myInteger) will have the same 1e-7 asymmetric split, as it is internally "moduloed" into the given integer range.
Answer by chomps32 · Jul 07, 2016 at 05:26 PM
To pick between 1 and 5, I would use %5 + 1.
15%5 = 0 + 1 = 1 |16%5 = 1 + 1 = 2 |17%5 = 2 + 1 = 3 |18%5 = 3+1 =4 |19%5 = 4+1 = 5
Randomly generate a number, % the distance between lowest number and highest number (1,2,3,4,5 = 5), then add the lowest number.
But why bother when Random.Range(1,5) does it for you in one line...
Answer by OnslaughtDestroyer · Feb 22 at 05:24 PM
Hey, it's 2022. and If you (not the poster) were looking for something different. Check this out.
float RandomXDir()
{
var randy = Random.Range(1, 4);
float randomXDir = 0;
if (randy == 1)
{
randomXDir = 10;
}
else if (randy == 2)
{
randomXDir = -10;
}
else if (randy == 3)
{
randomXDir = 0;
}
return randomXDir;
}//RandomXDir
then just put RandomXDir() inside whatever X. Like:
Vector3 victor = new Vector3(RandomXDir(), transform.position.y, RandomZDir());
So later you can:
Instantiate(balls, victor, balls.transform.rotation);
Your answer
Follow this Question
Related Questions
SOLVED! - Pick Number != These Other Numbers 2 Answers
Broadcast Message using RaycastAll 1 Answer
Normal distribution random 3 Answers
How to make death messages show at random? 1 Answer
Repeat Function 1 Answer