def misses_leadership(hit, wound, save, damage, wound_dice=3): return dice_up( Dice.from_dice(6), hit, lambda d: dice_up( wound_dice * Dice.from_dice(6), wound, lambda d: dice_down(Dice.from_dice(6), save, lambda d: damage,), ), )
def misses_standard(hit, wound, save, damage): return dice_up( Dice.from_dice(6), hit, lambda d: dice_up( Dice.from_dice(6), wound, lambda d: dice_down(Dice.from_dice(6), save, lambda d: damage,), ), )
def main(): fig, ax = plt.subplots(figsize=(8, 8), subplot_kw={"projection": "3d"}) NUMBERS = range(0, 13) results = [ sa_reroll(NUMBERS, Dice.from_dice(12)), sa_reroll(NUMBERS, 2 * Dice.from_dice(6)), ][1:] for result, colour in zip(from_results(results, only_positive=True), COLOURS): ax.plot_wireframe(*result, color=colour, alpha=0.5, cstride=0) ax.set_xlabel("Damage") ax.set_ylabel("Reroll from") ax.set_zlabel("Chance") ax.set_title(f"SA damage") plt.show()
def mbl_c_beam(leadership, armour, inv=7): for toughness in range(6, TOUGHNESS_LIMIT): yield ( toughness, misses_leadership( 3, leadership, min(armour + 5, inv), 2 * Dice.from_dice(6), ), )
def mbl(armour, inv=7): for leadership in range(1, 12, 2): yield ( leadership, misses_leadership( 3, leadership, min(armour + 5, inv), 2 * Dice.from_dice(6), ), )
def c_beam(level, armour, inv=7): for toughness in range(6, TOUGHNESS_LIMIT): yield ( toughness, 2 * misses_standard( 2, wound(6 + 2 * level, toughness), min(armour + 3, inv), (1 + level) * Dice.from_dice(3), ), )
import fractions import matplotlib from dice_stats import Dice if __name__ == "__main__": d = Dice.from_dice(6) + Dice.from_dice(6) print(d) d = 2 * Dice.from_dice(6) print(d) print( Dice.sum([ (1 * Dice.from_dice(6)).as_chance(fractions.Fraction(2, 6)), (2 * Dice.from_dice(6)).as_chance(fractions.Fraction(3, 6)), (3 * Dice.from_dice(6)).as_chance(fractions.Fraction(1, 6)), ])) print( Dice.from_dice(6).chances({ (1, 2): (1 * Dice.from_dice(6)), (3, 4, 5): (2 * Dice.from_dice(6)), (6, ): (3 * Dice.from_dice(6)), })) print(Dice.from_dice(6).removes([1, 2])) print(Dice.from_dice(6).reroll([])) print(Dice.from_dice(6).reroll([1])) print(Dice.from_dice(6).reroll([1, 2])) print(Dice.from_dice(6).reroll([1, 2, 3]))
def sa_reroll(rerolls, damage: Dice): for reroll in rerolls: new_damage = damage.apply_chances( {Range.from_range(f"[,{reroll}]"): lambda _: damage,}, lambda dice: dice, ) yield reroll, new_damage
def dice_up(dice, number, callback): return dice.apply_functions( {Range.from_range(f"[{number},]"): callback}, lambda d: Dice.from_empty() )
def crits(): return Dice.max(*2 * [Dice.from_dice(20)])
def fnp_damage(damage, fnp): return Damage.sum(amount - (fnp.non_repeat * amount).as_chance(chance) for amount, chance in damage.items())