#!/usr/bin/env python3 import argparse import itertools def calculate_odds(current_hp, level, static_bonus, hp_die): non_rolled_hp = hp_die + static_bonus * level rolled_hp = current_hp - non_rolled_hp average_rolled = rolled_hp / (level - 1) possible_rolls_each_level = list(range(2, hp_die + 1)) all_possible_rolls = itertools.product(*[ possible_rolls_each_level for _ in range(level - 1) ]) below_or_at_rolled_hp = 0 for n, result in enumerate(all_possible_rolls, 1): if sum(result) <= rolled_hp: below_or_at_rolled_hp += 1 probability_of_rolling_rolled_result_or_worse = below_or_at_rolled_hp / n return ( average_rolled, n, below_or_at_rolled_hp, n - below_or_at_rolled_hp, probability_of_rolling_rolled_result_or_worse, ) def main(): parser = argparse.ArgumentParser() parser.add_argument('--current-hp', type=int) parser.add_argument('--static-bonus-per-level', type=int, default=0, help=('Total static bonus per level, including ' 'CON bonus and feats')) parser.add_argument('--level', type=int) parser.add_argument('--hitpoint-die', type=int, choices=[6, 8, 10, 12]) args = parser.parse_args() avg, tot, below, above, prob = calculate_odds( args.current_hp, args.level, args.static_bonus_per_level, args.hitpoint_die) print('Average rolled:', avg) print('Total rolls:', tot) print('Number of rolls resulting in average or below', below) print('Number of rolls resulting in above average', above) print('Probability of rolling average or below:', prob) print('Percent chanc rolling average or below: %.2f%%' % (prob * 100)) if __name__ == '__main__': main()