Sign in to follow this  

Random Generation - Rare Powerups

This topic is 2393 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, hope this is the right form for this. Im currently making a random generator that spawns powerups every now and then. The problem is I'm trying to make some items more rare as you progress up in level and some items less rare the higher you get.

Here is what I have tried. Firstly I just tried to make items a set percentage

[code]
private int getPowerup()
{

int range = Random.Range(1, 101);

float atomic = 95;
float hammer = 60;

if(range >= atomic) {

return 9;

}else if(range >= hammer) {

return 10;

}

//else Gun
return 11;

}[/code]


Then I tried

[code]
private int getPowerup()
{

percentage = currentLevel / maxLevel;

int range = Random.Range(1, 101);

float atomic = 95 * (1 - percentage);
float hammer = 60 * percentage;

if(range >= atomic) {

return 9;

}else if(range >= hammer) {

return 10;

}

//else Gun
return 11;

}[/code]


But this doesn't seem to be exactly what I was after either. Would anyone have any recommendations as to what I should try?

Thanks in advance

Share this post


Link to post
Share on other sites
It looks like you have Hammer as being very common at low level and less common at higher level, and Atomic as less common at low levels and more common at high levels?

Otherwise make sure percentage is properly evaluated as a float between 0 and 1 (you might have to cast the variables in the ratio?)

Share this post


Link to post
Share on other sites
Hmm, I'm pretty sure I posted a reply yesterday? ok ill try again :)
[color=#1C2837][size=2]
[b][url="http://www.gamedev.net/user/156846-prestochung/"]PrestoChung[/url]: [color=#000000][size=3]Thanks for the reply. Thats sort of the effect that I was going for. I want the 2 properties to increase and decrease as the level nears the last. Problem with the above code is the if statement. Eventually the hammer wont have any chance at all because the atomic will be such a high percentage it will just skip hammer in the if statement. I think I have a solution now though. Ill give it a shot and let you know how it goes. Thanks again[/size][/color][/b]
[/size][/color]

Share this post


Link to post
Share on other sites
The method you've found should work, but may become unhandy. Assume that at the beginning 1% probability for item A and (therefore) 99% for item B is wanted. Then you need to generate a 100 element array where 1 element is set to A and 99 is set to B.

You may use a iterative solution instead, similar to your 1st code snippet in the OP. However, such a solution does a search and will hence be less runtime efficient than the above one.

Assume that the probabilities p[sub]i[/sub] for j items, 0 <= i < j, are given. Then generate a uniformly distributed random number n in [0,1] and compare it with partial sums of the probabilities and pick the belonging item as follows:

pick item i where p[sub]i-1[/sub] < n <= p[sub]i[/sub] with p[sub]-1[/sub] = -infty (any number less than 0 would work)

There is a little inconsistency because item #0 is in the closed range [0,p[sub]0[/sub]] while any other item is in a left-sided open range (p[sub]i-1[/sub],p[sub]i[/sub]], but that can be neglected for any practical purposes.

The above can be accomplished for example by
[code]
for( item=0; item<noofItems-1 && n>probabilities[item]; ++item) {
n -= probabilities[item];
}
// use 'item' here as needed
[/code]
where the item<noofItems-1 is there just to avoid array accesses out of bounds due to numerical inaccuracies.

Another way would be to pre-compute an array with the partial sums

[code]
sum = 0;
for( item=0; item<noofItems-1; ++item) {
sum += probabilities[item];
summedProbabilities[item] = sum;
}
summedProbabilities[noofItems-1] = 1; // a value >1 can be used for absolute safety
[/code]
where the last line again is for avoiding array accesses out of bounds later on. Then the assessment can be done like

[code]
for( item=0; n>probabilities[item]; ++item) {}
// use 'item' as needed here
[/code]
This solution is a bit more runtime efficient than the former one, I think, but requires an additional array (of a length equal to the number of item types).

Share this post


Link to post
Share on other sites
Just a thought, but instead of actually generating the series of items weighted number of times, you can act like you generated it by simply assuming it is in the range, so for example

[source]
int weapons[] = { ROCK, HAMMER, GUN };
int weight[] = { 7, 2,1} ; //70 % , 20% , 10% -- note should depend on the level

int pickedWeapon = rand() % 9 + 1 ; // 1-9
//[1,7] -> pick rock , P(X) = 70% since 7 different range
if( 1 <= pickedWeapon <= weight[0] ) { return weapon[0]; }
//[8,9] -> pick hammer , P(X) = 20% since 2 different range
else if(1 + weight[0]<= pickedWeapon <= weight[1] + weight[0]) { return weapon[1]; }
//[10,10] -> pick gun, P(X) = 10%, since 1 different range
else if(1 + weight[0] + weight[1] <= pickedWeapon <= weight[2] + weight[1] + weight[0]){ return weapon[2]; }
[/source]

The above was just an idea,nothing definite.

Share this post


Link to post
Share on other sites

This topic is 2393 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this