#rarities

1 messages · Page 1 of 1 (latest)

lone dawn
#
struct Rarity{
  string name;
  int likelihood; // Defined as inverse of probability.  So 1/10 would be 10.  Or 1/100 would be 100.
}

//This list needs to be defined with rarest item at top and least rare at bottom.
List<Rarity> rarities = new List<Rarity>{
  new Rarity("legendary",100000000),
  new Rarity("epic",1000000),
  new Rarity("rare", 1000),
  new Rarity("uncommon", 10),
  new Rarity("common", 0) // Last item is just catch all has to always be 0
};


int numberOfItemsToAssignRarities = 10000; // The number of items you want to generate

foreach(Rarity rarity in rarities){
  if (rarity.likelihood == 0){
    // The catch all rarity.  Anything that didn't get assigned a rarity
    Debug.Log($"There were {numberOfItemsToAssignRarities} of rarity {rarity.name}");
    break;
  }
  int randomNumber = Random.Range(0,rarity.likelihood+numberOfItemsToAssignRarities+1);
  int numberOfItemsOfThisRarity = randomNumber - rarity.likelihood;
  if(numberOfItemsOfThisRarity > 0){
    Debug.Log($"There were {numberOfItemsOfThisRarity} of rarity {rarity.name}");
    numberOfItemsToAssignRarities -= numberOfItemsOfThisRarity;
  }
}
#

idk how well this would actually work. Just came up with it and typed it up in discord. No idea if it has compile errors or not

sturdy peak
#

tbh at a certain point. (definitely before 1e100) it’s all going to converge onto the same values

lone dawn
#

Yea... thought about that as well.

#

Tricky little problem to solve.

#

Could take the probability.
And do something like:

decimal probability = 0.001;
int items = 100;

float randomNumber = Random.Range(0.0, 1.0*items);
int itemsInRange = (randomNumber-(items*(1-probability)))/probability;
if(itemsInRange < 0){
  itemsInRange = 0;
}
#

Though you're going to overflow your variables pretty quickly doing something like that

sturdy peak
#

I had a slight idea that would pretty much make the random generation O(1), by just partitioning a double (with value of 1) in a bunch of spots and multiplying each partition by 1e100. But then the issue is how to partition it.

#

and i guess it would be pretty unnatural

#

since a lot of the values would end with a 0000 or something

sharp oar
#

ending with a 0000 is not a problem

#

since its not going to show all the digits

sharp oar
#

i noticed this is the main code

#

'''
int randomNumber = Random.Range(0,rarity.likelihood+numberOfItemsToAssignRarities+1);
int numberOfItemsOfThisRarity = randomNumber - rarity.likelihood;
'''

#

but i dont understand it

lone dawn
#

After thinking through it more don't think that first code block will work

#

The second code block has a higher likelihood of working. But when your numbers get really big you'll overflow the vars and run into issues.

sharp oar
#

so this?
float randomNumber = Random.Range(0.0, 1.0items);
int itemsInRange = (randomNumber-(items
(1-probability)))/probability;

lone dawn
#

yea

sharp oar
#

k

lone dawn
#

That code would generate the number of items of a specific rarity. Given the number of items and the probability of that rarity

#

again untested. Just typed it up not sure if it's right

sharp oar
#

ok

#

can the randomNumber be int?

#

like without decimals

lone dawn
#

It has to be some kind of decimal variable.

sharp oar
#

now i have this

        float randomNumber = Random.Range(0.0, jps);
        BigInteger itemsInRange = (((int)(randomNumber*10000000000L)-((jps*(int)((1-probability)*10000000000L))/10000000000L)/10000000000L)/(int)(probability*10000000000L))/10000000000L;
#

now the problem is i want it to be with bigint

#

how can i do that?