For modelling a simple game of cricket, Considering a batsman has a single attribute rating
. I can go about deciding run chances by weighted probabilities. Something like
if batsman.rating <= 30:
# map of run: probability
probabilites = {0: 0.7, 1: 0.1, 2: 0.1, 3:0.5, 4:0.5, 6:0 }
elif 30 <batsman.rating < 60
probabilites = {0: 0.7, 1: 0.1, 2: 0.1, 3:0.5, 4:0.5, 6:0 }
else:
probabilites = {0: 0.7, 1: 0.1, 2: 0.1, 3:0.5, 4:0.5, 6:0 }
Now there are two challenges:
- What if I want finer control over batsman.rating and probabilities? How do I manage to keep the sum of all probabilities equal to 1?
- How to manage a second attribute to a batsman, let's say aggression. Which can lower chances of 0 and increase chances of 6?
Initially tried dealing to have finer control like below:
# map of batsman.rating: probability,
rating_to_zero_chances = {0: 0.9, 10: 0.7, 30: 0.5, 60: 0.3, 90: 0.1}
rating_to_one_chances = {0: 0.9, 10: 0.7, 30: 0.5, 60: 0.3, 90: 0.1}
chances_of_zero = <some library>.interpolate(rating_to_zero_chances).yvalue(batsman.rating)
chances_of_one = <some library>.interpolate(rating_to_one_chances).yvalue(batsman.rating)
.
.
.
#do this for each run
The problem with this is that I cannot interpolate the probabilities such that they are equal to 1, Since the slope of runs for the interpolated data are different
For challenge 2, Initially tried handling it by making a probability density function and shifting the mean
of the curve if the aggression is more. This creates a problem when there is a 3rd or 4th attribute added (such as timing etc are added).
Currently am planning to deal with a single run with its chance, rather than having to sum their probabilities to 1 like below:
zero_chance = interpolate(rating_to_zero_chances).yvalue(batsman.rating)
zero_chance += aggression / 100 # assuming aggression on 1-100
is_zero_scored = binom([0,1], p=zero_chance).random()
if is_zero_scored:
return 0
one_chance = interpolate(rating_to_one_chances).yvalue(batsman.rating)
one_chance += aggression / 90 # assuming aggression on 1-100
is_one_scored = binom([0,1], p=one_chance).random()
if is_one_scored:
return 1
. # similarly for 2
.
.
Is there any neater way to do this? I am new to game development and had learned about probability distributions recently. Are there some theoretical/ practically established concepts I should be looking at? How do game developers handle and balance different chances of an event?