Math - Random Integer, exclude specific integers?

Discussion in 'Triggers & Scripts' started by Marine, Apr 25, 2016.

1. Marine

Joined:
Mar 17, 2012
Messages:
102
Resources:
0
Resources:
0
As title says. Need to generate a random number with multiple particular numbers excluded. Can it be done?

2. Chaosy

Joined:
Jun 9, 2011
Messages:
10,609
Resources:
18
Maps:
1
Spells:
11
Tutorials:
6
Resources:
18
Technically impossible. You need to re roll each time, this should be done with a loop to make it easy.

loop 1-3
roll = number between 1-100
if roll is not equal to 53 then
exit loop
endloop

edit: A more effective solution (maybe, I haven't exactly benchmarked it)
Make an array of numbers.
x[1] = 22
x[2] = 66
x[..] = 45
x[99] = 98

Then do something like
roll = random number between 1-99
x[roll] is now the one that has been randomized.

3. IcemanBo

Joined:
Sep 6, 2013
Messages:
6,165
Resources:
22
Maps:
3
Spells:
11
Template:
1
Tutorials:
4
JASS:
3
Resources:
22
Trial and error, making a maths formula, or defining a custom array which only includes valid input.

Spell Reviewer

Joined:
Jan 18, 2005
Messages:
25,477
Resources:
3
Maps:
1
Spells:
2
Resources:
3
If you are after random integers within a small range (eg 0 to 8191) you can use an array to map a continuous random integer into a non-continuous range.

5. Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
Easily doable actually.

Pick the random int from minvalue to maxvalue-invalids
This initially includes the invalids and excludes a number of valid inputs.
To make it work you check for every input that you consider invalid and replace it with a valid input that is originally excluded.

Example:
You want a random number from 1 to 100, but not 49:
*Pick a random from 1 to 99
*If the random is 49, then use 100.

If you want to exclude multiple inputs you just need to use more ifs or maybe an array.

6. Chaosy

Joined:
Jun 9, 2011
Messages:
10,609
Resources:
18
Maps:
1
Spells:
11
Tutorials:
6
Resources:
18
Well, what the point of that? While it does what he requested technically, it seems unusable from a practical code perspective.

My guess is that he got an array of something which he uses randomly, and the want to filter out certain locations at some point during the map.
Of course there would be other solutions to that, but this is one of them.
Example:
CreateUnit(..., unitSpawn[random], ..)

In which case doing your method wont work. Because he likely got let's say 10 spawn points, setting number 5 to spawn point 11 will not work. And setting it to 10 would work, but make the chance of spawn point 10 twice as high which is counter productive to what he wants to achieve.

7. Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
It's trivial to use a variable.

Joined:
Dec 11, 2014
Messages:
1,889
Resources:
3
Maps:
2
Spells:
1
Resources:
3
I made such a thing for my school once, it deindexes from a dynamic series of string arrays with numbers in them, and then rolls a number and uses it in the array bracket.
Exclusion is with deindexing the array that has the wanted value.

I did it with C# which means it's doable in (v)JASS.

I can attach the .exe file.

9. Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
I don't see how it wouldn't work. The point is to exclude some numbers, so what my approach does is that it effectively swaps them with the values at the end and at the same time avoids double chance.
As I said, you can and should first put the number in a variable and then change the variable if it doesn't fit the criteria. There is no need for rerolls because this is specifically a remapping task.
There is also no need to use an array because the set is continuous except for the few numbers that you want to exclude.

10. Chaosy

Joined:
Jun 9, 2011
Messages:
10,609
Resources:
18
Maps:
1
Spells:
11
Tutorials:
6
Resources:
18
I get what you mean now. I misread you original post just slightly.
I did not 'register' the part that you have an 1-100 array and then roll 1-99. I assumed that you rolled between 1 and the array size (100).
In that case it does indeed work fine.
But it's still not quite perfect (though, still good considering how easy it is).

Once more if we have 10 spawn points for a unit, and you want it to be random.
You random between 1-9 and set spawnPoint[x] = spawnPoint[10] if you want to exclude one spawn point.
However this makes the tenth location only work while another one is 'disabled'. Which may not be something you want. If that was okay you might as well change the value of spawnPoint[x] to begin with.

Maybe I'm misunderstanding something again but that's how I translate it as of now.

11. Xonok

Joined:
Mar 27, 2012
Messages:
3,042
Resources:
8
Spells:
3
Tutorials:
5
Resources:
8
Overwriting spawn points probably wouldn't be a good idea because it erases traces. If you want to mess with them dynamically like this, then the whole thing will become considerably more complicated.
For a static solution, the way I proposed will work with any number of inputs (although having a counted array of disabled values would make sense after a certain amount).
It would be nice if OP specified what they need it for. Atm we have to assume too much.

12. Marine

Joined:
Mar 17, 2012
Messages:
102
Resources:
0
Resources:
0
Thanks for the replies, I've just decided that because I only need a few ints (12), I just used a Unit Group and removed units from the group as their numbers (custom value) were called.