Dice Stats¶
Contains all the documentation for the files under /src/dice_stats.
Magic Mixins¶
Magic methods for Dice class.
These add different types of magic methods to the dice class. Given the amount of magic methods I found it to be clearer to split out the definitions. This means numeric comparisons are located in the numeric.py file.
Internal Types¶
Generic types used across the project.
Dice¶
High level dice helper functions.
-
class
dice_stats.dice.
Dice
(chances=None, total_chance=Fraction(1, 1)) Dice class.
-
apply_dice
(chances, default=None) Change chances to provided dice.
This changes the values of the host dice, to the values of the provided dice. It does so by changing the provided dice to the correct chance.
- Parameters
chances (
Dict
[Iterable
[Union
[Real
,Integral
]],Dice
]) – A mapping of all the Chances Value and dice to change.default (
Optional
[Dice
]) – A dice to use as the default when chances doesn’t cover all possible Chances Value.
- Return type
Dice
- Returns
A new Dice that acts as if these multiple dice rolls happen in one throw.
Say we’re playing a game where you roll a die to attack people. You normally do 1-6 damage, however sometimes there’s a chance to do 1-4 - say you had bad footing. To determine what dice you use use throw a d3 before using either the d6 or the d4. On a 1 you use the d4, otherwise it’s the d6. To find the chances is easy with this function.
print( Dice.from_dice(3) .apply_dice( {(1,): Dice.from_dice(4)}, Dice.from_dice(6), ) )
Dice[1]( 1: 19.4% 7/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 11.1% 1/9 6: 11.1% 1/9 )
-
apply_functions
(chances, default=None, apply=<function Dice.<lambda>>) Apply a callback to the provided chances.
This is the more complex version
dice_stats.Dice.apply_dice()
. With this version you can pass a callback that mutates the segment of the dice provided.This callback is given a segment of the host dice, this means that the callback has all the information that it should need, as this dice would have all the Chances Value and Chances Chance it needs. The Total Chance will also be the correct for that segment of the dice results.
The callback then has to return a dice object that that segment gets mutated to. For example if you’re using this to reroll dice, then one function would return the segment provided, where the other would return the host dice of sorts.
- Parameters
chances (
Dict
[Iterable
[Union
[Real
,Integral
]],Callable
[[Dice
],Dice
]]) – The mapping that holds the outputs.default (
Optional
[Callable
[[Dice
],Dice
]]) – The function to apply if there are missing values.apply (
Callable
[[Dice
],Dice
]) – A function to mutate each dice segment before they reach thechances
callback.
- Return type
Dice
- Returns
New dice that’s been fully mutated by the callbacks.
To expand on the previous example, if we have a d6 and we’re allowed to reroll 1s once, then we could use the following code.
Note
This functionality is already builtin to the
dice_stats.Dice
class. You can instead use thedice_stats.Dice.reroll()
method to do this.print( Dice.from_dice(6) .apply_functions( {(1,): lambda d: Dice.from_dice(6) @ d}, lambda d: d, ) )
Dice[1]( 1: 2.8% 1/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 19.4% 7/36 6: 19.4% 7/36 )
-
as_total_chance
(total_chance) Change Total Chance.
This adjusts each Chances Chance by the scale of the old and new Total Chance.
- Parameters
total_chance (
Union
[Fraction
,Dice
,int
]) – Desired Total Chance.- Return type
Dice
- Returns
A new dice with the specified Total Chance.
For example, say we have a d3 which has a 100% Total Chance, however it should be a 200% Total Chance. Then we use this function to change it. It will also change all the Chances Chance from 1/3 to 2/3.
d3 = Dice.from_dice(3) print(d3) print(d3.as_total_chance(Fraction(2, 1)))
Dice[1]( 1: 33.3% 1/3 2: 33.3% 1/3 3: 33.3% 1/3 ) Dice[2]( 1: 66.7% 2/3 2: 66.7% 2/3 3: 66.7% 2/3 )
-
classmethod
from_dice
(sides, total_chance=Fraction(1, 1)) Make a dice from a number of sides.
This is a very useful convenience function, this is the most common way to build dice as it builds dice with an equal chance to land on all faces.
- Parameters
sides (
Integral
) – Amount of sides the n-sided dice has.total_chance (
Fraction
) – Total Chance.
- Return type
Dice
- Returns
A fair n-sided dice.
Below is an example of some of the smaller dice you can create with this.
print(Dice.from_dice(1)) print(Dice.from_dice(2)) print(Dice.from_dice(3)) print(Dice.from_dice(6))
Dice[1]( 1: 100.0% 1/1 ) Dice[1]( 1: 50.0% 1/2 2: 50.0% 1/2 ) Dice[1]( 1: 33.3% 1/3 2: 33.3% 1/3 3: 33.3% 1/3 ) Dice[1]( 1: 16.7% 1/6 2: 16.7% 1/6 3: 16.7% 1/6 4: 16.7% 1/6 5: 16.7% 1/6 6: 16.7% 1/6 )
-
classmethod
from_external
(chances, total_chance) Create a dice from the Chances form.
This doesn’t use the Internal Chances form, and so eases use when not using that form.
-
classmethod
from_prev_total_chance
(chances, chance, prev_chance) Change a dice from one Total Chance to another.
This is a deprecated function, this is likely better expressed by using
dice_stats.Dice.from_external()
anddice_stats.Dice.as_total_chance()
.- Parameters
chance (
Fraction
) – New Total Chance amount.prev_chance (
Fraction
) – Old Total Chance amount.
- Return type
Dice
- Returns
A dice with new chances.
-
max
(other=None) Get the maximum result from two dice.
Say you’re playing a game which allows you to roll two dice and take the highest as your result. To do this you would need a cartesian max, which is what this function performs.
- Parameters
other (
Optional
[Dice
]) – Another dice to get the maximum value from. If unset then it uses itself.- Return type
Dice
- Returns
A new dice of the chances of getting the maximum.
Say you have can roll two d6s and use the maximum, that would simply be:
print(Dice.from_dice(6).max())
Dice[1]( 1: 2.8% 1/36 2: 8.3% 1/12 3: 13.9% 5/36 4: 19.4% 7/36 5: 25.0% 1/4 6: 30.6% 11/36 )
-
partition
(values) Remove multiple Chances Value from the dice.
Split the dice into two. This removes the values provided in the values argument out of the dice, and then returns the rest of the values in a separate dice.
- Parameters
values (
Iterable
[Union
[Real
,Integral
]]) – Selection of Chances Value to remove from the dice.- Return type
Tuple
[Dice
,Dice
]- Returns
Returns two different dice, one with the wanted values, the other with the unwanted values.
For the most part this is used internally when using one of the apply functions or the reroll function. However its existence helps makes these functions possible and easy to implement.
To showcase this we’ll define a basic reroll function using this function.
Note
This functionality is already builtin to the
dice_stats.Dice
class. You can instead use thedice_stats.Dice.reroll()
method to do this.def reroll(dice, values): rerolled, kept = dice.partition(values) return Dice.sum([ kept, dice.as_total_chance(rerolled.total_chance), ]) print(reroll(Dice.from_dice(6), (1,)))
Dice[1]( 1: 2.8% 1/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 19.4% 7/36 6: 19.4% 7/36 )
-
reroll
(values) Reroll specified values.
Since this is a common operation on dice this is some sugar for it. It should be noted that whilst this handles the simple instances of rerolling, there are some more complex situations that can only be handled through custom functions or the
dice_stats.Dice.apply_functions()
method.For the simple situation of being able to reroll a range of values once then this is all you need.
- Parameters
values (
Iterable
[Union
[Real
,Integral
]]) – Collection of Chances Value.- Return type
Dice
- Returns
A new dice factoring in rerolls.
print(Dice.from_dice(6).reroll((1,)))
Dice[1]( 1: 2.8% 1/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 19.4% 7/36 6: 19.4% 7/36 )
-
classmethod
sum
(dice) Add multiple dice together, increasing their Total Chance.
This is mostly used when you have multiple partial dice that you need to add together only adding the chances together. For example lets say we have a 2/3 chance for our outcome to be a d6 or a 1/3 chance that the outcome is a d4 then the total outcome would be the result of those two dice added together, but not in the common form -
d6 + d4
.print(Dice.sum([ Dice.from_dice(6, total_chance=Fraction(2, 3)), Dice.from_dice(4, total_chance=Fraction(1, 3)), ]))
Which correctly results in:
Dice[1]( 1: 19.4% 7/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 11.1% 1/9 6: 11.1% 1/9 )
As we can see, the result totals to 100%, and there is a significantly higher chance to get a 1-4 then 5 or 6. This shows pretty clearly that the outcome is only adding the chances together.
For the most part you can normally use a different function than this one if you need to get this sort of output. Lets say the game we’re playing says to roll a d3 to decide between either the d4 or the d6 to be rolled to get the result. On a 1 you roll the d4 otherwise it’s the d6, which could be expressed as:
print( Dice.from_dice(3) .apply_dice( {(1,): Dice.from_dice(4)}, Dice.from_dice(6) ) )
Dice[1]( 1: 19.4% 7/36 2: 19.4% 7/36 3: 19.4% 7/36 4: 19.4% 7/36 5: 11.1% 1/9 6: 11.1% 1/9 )
- Return type
Dice
-
Display¶
Some functions to make displaying dice data easier.