How to create a probability by a given percentage?
Asked Answered
S

4

7

I'm trying to create a percentage-based probability for a game. E.g. if an item has a 45% chance of a critical hit, that must mean it is 45 of 100 hits would be critical.

First, I tried to use a simple solution:

R = new Random();
int C = R.Next(1, 101);
if (C <= ProbabilityPercent) DoSomething()

But in 100 iterations with a chance of e.g. 48%, it gives 40-52 out of 100. Same goes for 49, 50, 51. So, there is no difference between these "percents".

The question is how to set a percentage of e.g. 50, and get strictly 50 of 100 with random? It is a very important thing for probability of rare item finding with an opportunity to increase a chance to find with an item. So the buff of 1% would be sensinble, because now it is not.

Sorry for my bad English.

Sudhir answered 12/11, 2012 at 10:25 Comment(8)
You have to understand that "strictly 50% with random" is not random.Anthracene
Make sure you understand randomness.Gorey
That means if a have 50% chance of get a "1" in a binary sequence of 10 bits it would be 0, 1, 0, 0, 0, 1, 1, 0, 1, 1 for example. But still - 5 "1"'s. Random occurencies, strict count.Sudhir
@maelstrom: Then it's not really random. It's random from within a pool, not really random. Random like a deck of card, not random like a dice throw.Maidy
@Sudhir no, if you add "strict count" then it is not random in the normal sense of things.Herrle
@Maidy basically, I need to input an N percent of a probability, and it calculates a sequence of 1 and 0 count of 100, with N "1". And mix it up. Right?Sudhir
additionally; over which window of 100 roles must it be measured? if it is a sliding window, then the only valid solution is to keep repeating the same 100 outcomes - extremely non-random.Herrle
Possible duplicate of Random number generator only generating one random numberClipfed
H
9

You need to think only in terms of uniform distribution over repeated rolls.

You can't look over 100 rolls, because forcing that to yield exactly 45 would not be random. Usually, such rolls should exhibit "lack of memory". For example, if you roll a dice looking for a 6, you have a 1-in-6 chance. If you roll it 5 times, and don't get a six - then: the chance of getting a 6 on the next roll is not 1. It is still 1 in 6. As such, you can only look at how well it met your expectation when amortized over a statistically large number of events... 100,000 say.

Basically: your current code is fine. If the user knows (because they've hit 55 times without a critical) that the next 45 hits must be critical, then it is no longer random and they can game the system.

Also; 45% chance of critical hit seems a bit high ;p

Herrle answered 12/11, 2012 at 10:32 Comment(4)
@Sudhir I thought it was just the "awesome holy chaos death hammer of maximum carnage"Herrle
thanks a lot, I've got your point. Maybe I've taken a little serious over a concept of Diablo II Magic Find. I thought it's far more complicated than my code.Sudhir
DII MF is even more complicated because of its diminishing returns. 100% MF doesn't guarantee only finding blue and better weapons. :)Gorey
@Gorey If you can tell me more about this system it would be much more appreciated. I understand that "diminishing returns" means difference between lesser values is much more, than between bigger. But how can I implement such system?Sudhir
M
4

I'm trying to create a percentage-based probability for a game. E.g. if an item has a 45% chance of a critical hit, that must mean it is 45 of 100 hits would be critical.

No, that's not true. You missunderstud completely the concept of Probability. You dont want a "percentage-based probability", you want a "percentage-based random distribution of 100 samples".

What you need is a "bag of events", 45 of them "crytical" and 55 of them "non crytical". Once you pick an event from the bag, you only have the remaining events to pick the next time.

You can model it this way:

Initialize two integer variables Crytical and NonCrytical so that they sum exactly 100 according to the desired percetnages.

Get a random value from 1 to Crytical+NonCrytical

If the random value is less than the value of Crytical, let you hit be crytical and:

   Crytical = Crytical -1

Else, let your hit be non-crytical

   NonCrytical = NonCrytical-1

End If

Repeat until Crytical+NonCrytical = 0
Monophthong answered 12/11, 2012 at 10:38 Comment(0)
Q
4

Since I am no expert in C# I will use a C++ function for ease but still applicable for any language.

rand() - random number generator.

//33.34%
double probability = 0.3334;

//divide to get a number between 0 and 1
double result = rand() / RAND_MAX;
if(result < probability)
   //do something

I have used this method to create very large percolated grids and it works excellent for precision values.

Quoits answered 12/8, 2013 at 20:48 Comment(0)
G
0

The thing is, with Random you might want to initialize this class only once.

This is because Random uses the system time as a seed for generating random numbers. If your loop is very fast it could happen that multiple Random-instances are using the same seed and thus generating the same numbers.

Check the generated numbers if you suspect this is happening.

Besides this, inherent to Randomness is that it won't give you exact results. This means that even with a 50/50 chance it could happen that a sequence of 100 "heads" or "tails" gives "heads" 100 times.

The only thing you can do is create the Random-instance once and live with the results; otherwise you shouldn't use Random.

Gorey answered 12/11, 2012 at 10:31 Comment(2)
Okay, he said "iterations" so I thought he may have used a loop, so I wanted to warn him about the possible side effects of initializing Random in a loop.Gorey
I used a loop for a test purpose. And I initialized Random before loop.Sudhir

© 2022 - 2024 — McMap. All rights reserved.