In my game, most dice rolls are compared to a probability expressed as a fraction. Eg. you have a 1/3 probability of missing your shot or a 1/6 probability of scoring a critical hit. Right now, I just do something like this:
def roll_die(numerator,denominator):
die_roll=random.randint(1,denominator)
if die_roll<=numerator: return True
else: return False
This "just works", and on a simple enough level for even me to understand, but I've been thinking about drawing dice rolls from a set pool of results. This would mean results are more stable over time, but should still allow for streaks of bad/good luck and so. Accompanying functions might look something like:
result_pool=[]
for i in xrange(1,601): result_pool.append(i) # insert numbers 1 though 600 into list
def roll_die(numerator,denominator):
die_roll=result_pool.pop(random.randint(0,len(result_pool)-1) # pops a random number, removing it from the list
result = Fraction(die_roll,600)
prob = Fraction(numerator,denominator)
if result<= prob: return True
else: return False
… and whenever result_pool gets empty, refill with numbers 1-600. This kind of solution is commonly used, though I don't exactly remember it's name at the moment. (I'm using something similar for monster placement in the upcoming release, and it yields a nice and balanced result: RNG can still screw you over during map generation, but you won't get either levels devoid of life or levels that are just cramped with enemies.)
A few questions:
* How large would you deem it reasonable to make the result_pool list? A smaller list yields more predictable results, obviously. The base probability for most actions is 5/6, and I can't imagine any probability going below 1/60 or above 59/60, so I can probably go as low as that – len(result_pool)==60, that is. But the player shouldn't be "counting bullets" either, in the sense of being able to know that "currently, my nominal P=1/6 in practice translates into P=1/2."
* Would it be a good idea to keep separate result_pool lists for the player and for other critters? If the idea is to "even out" the results a bit, the player can still get screwed if pulling all the bad results while mobs pull all the good results. I guess keeping one list for the player plus allies, and one list for opponents, seems fair.
Any thoughts? Maybe I'm just wasting time thinking about this. I definitely think it makes sense to nudge stuff like encounter/treasure tables in this way, but not so sure it really has much to say for tactical dice rolls. And too much predictability is not a good thing, either.
As always,
Minotauros