Probability basics

Started by
7 comments, last by alvaro 12 years, 2 months ago
Sorry if this is the wrong section.

I'm having trouble with probability for part of the game I'm working on.

Basically, it's when a player tries to steal an item from a shop.

Now, the probability of success is based on their thieving level and on the price of the item, so the higher the price of the item, the harder it is to successfully steal, and the higher their level is makes it a bit easier.

They can't steal from shops at all until level 15, so that's where it starts.

At the moment all I've been able to come up with is a crappy little function which takes the cost of the item, adds on 20, then deducts their level, then multiplies it by about 3. Why 20 and why 3? No reason, I was just trying to pick some numbers which make the odds look roughly how I was hoping they'd be when I test it all in a loop with different costs and levels and whatnot.


$maxOdds = 20 + ( 3.15 * $cost);
$maxOdds -= $lvl ;
$maxOdds = ceil($maxOdds);


Problem is, I am very bad at maths. I have tried to look up how things like probability is done in games (and in general algorithms), but I've never really understood maths beyond the basics, and looking at all that notation in the articles and sites I've found just confuses the hell out of me.


Has anyone had to so something similar to this before and would be able to offer me any advice or tips as to how they achieved it? Or how they would achieve it if they were going to attempt it? I'm not looking for someone to just do it, I'd like to be able to do it myself, but I feel like I need some guidance on how to go about it.

Thanks.
Advertisement
There is no principled way to do this, but I'll give you a few ideas. Think of what the range of prices and the range of skill levels is. Come up with a few scenarios (some for typical situations, some extreme) and decide what you roughly want the probability to be in each case. Then try to fill in a formula that roughly gives you what you want.

Since you only have two parameters (price and skill level), you can think of the function that maps the two parameters to a probability as being an image which maps two coordinates to a gray level. If you figure out how dark you want each point to be, perhaps you can just describe your function as a small image (say 8x8) and use bilinear filtering to find the value for any combination of price and skill level. If your prices might vary in a large range (say, from candy to diamonds), you may want to use the logarithm of the price instead of the price directly as a coordinate for the image.

Another idea (perhaps for the more mathematically inclined) is to use a formula like in logistic regression:
log_price = log(price)
F(log_price, skill_level) = 1/(1+exp(-(A*log_price + B*skill_level + C)))

You can find values for A and B that will give you results that are roughly what you want. Since higher price means higher probability, A>0. And similarly, B<0. C just sets a global adjustment of how easy it is to steal in general.

[EDIT: I forgot about C in my first attempt.]
Always encapsulate all logic like this into a single function in your program, so that you never have the code written twice in your codebase, and more importantly, it explicitly makes you think what are good inputs and outputs to your function. Here's a simple one:


function ProbabilityToSteal(playerLevel, itemPrice)
{
if (playerLevel < 15) return 0; // Never succeed at below level 15. (note that this if() produces a discontinuity, but that might not be a big deal at all)
return playerLevel * 5 // Each player level adds a +5% into the rate of success.
- itemPrice / 100; // Each $100 reduces 1% of the probability to succeed.
}

For a character of level 15, this code gives a 50% chance to steal an item of value $2500 (you can see that by plugging in the values), 49% to steal an item of value $2600, 48% to steal an item of value $2700, and so on. If you want to adjust the ratios, change the factors.

That function is a linear function in both input variables. The big question is to get a grasp of what kinds of models you can build with a linear function like that, and whether you want to have something more complicated.
Oh, and to add to the previous, the function is intended to return a value in the range [0, 100], which you use as the probability to succeed (you might want to clamp the return value to that range as well)
Thanks
Went for this in the end, as it was the only way I could get it to work how I wanted it. Not exactly elegant, but seems to get the job done.



function successOdds($lvl, $cost)
{

$odds = $cost;
$odds += 15;
$odds += (($cost + 15) - $lvl);

$x = 0.15;


if($lvl >= 150)
{
if($cost >= 1000)
{
$x = 9.2;
}
}

elseif($lvl >= 80)
{
if($cost >= 100)
{
$x = 1.34;
}

elseif($cost >= 50)
{
$x = 0.66;
}
elseif($cost >= 20)
{
$x = 0.25;
}

}
elseif($lvl >= 50)
{

if($cost >= 50)
{
$x = 0.66;
}
elseif($cost >= 20)
{
$x = 0.25;
}

}

elseif($lvl <= 20)
{

if($cost > 2)
{
$odds = $odds * 1.5;
}

}

$odds -= ($lvl * $x);


if($odds < 1){$odds = 1;}

return $odds;

}
What does that function return? Is it the inverse of the probability of success?

It does have some funny features. For instance, if you are trying to steal something with a cost of 40, as your level increases, this is what the function returns:
successOdds(10, 40) = 148.5
successOdds(15, 40) = 140.25
successOdds(20, 40) = 132
successOdds(25, 40) = 81.25
successOdds(30, 40) = 75.5
successOdds(35, 40) = 69.75
successOdds(40, 40) = 64
successOdds(45, 40) = 58.25
successOdds(50, 40) = 47.5
successOdds(55, 40) = 41.25
successOdds(60, 40) = 35
successOdds(65, 40) = 28.75
successOdds(70, 40) = 22.5
successOdds(75, 40) = 16.25
successOdds(80, 40) = 10
successOdds(85, 40) = 3.75
successOdds(90, 40) = 1
successOdds(95, 40) = 1
successOdds(100, 40) = 1
successOdds(105, 40) = 1
successOdds(110, 40) = 1
successOdds(115, 40) = 1
successOdds(120, 40) = 1


It seems strange that it would transition so abruptly from "nearly impossible" to "piece of cake" around level 85...
It's not a % probability, it's a 1 in n chance of it being successful. So in that case, at lvl 1 you'd have a 1 in 148 chance of stealing a 40 cost item, 1 in 3 at lvl 85. 1 in 1 > 85

The problem was I just couldn't get it to smoothly increase/decrease at the levels & costs I wanted, so I had to add in several if statements to change the modifier.

What does that function return? Is it the inverse of the probability of success?

What does that function return? Is it the inverse of the probability of success?



It's not a % probability, it's a 1 in n chance of it being successful.



So it is the inverse of the probability.

The probability is a much nicer number to work with, so I recommend you model that and then invert the number at the end if you want.

Did you understand what I suggested with the image method? I can say it in other words: Pick the probability you want for a coarse grid of values and interpolate in between them.

This topic is closed to new replies.

Advertisement