Skip to content

Instantly share code, notes, and snippets.

@mbutler
Last active February 5, 2024 22:24
Show Gist options
  • Save mbutler/4c2ab80b0db99aebca44272ce39542fc to your computer and use it in GitHub Desktop.
Save mbutler/4c2ab80b0db99aebca44272ce39542fc to your computer and use it in GitHub Desktop.
working with dice pools
import random
import collections
def roll_dice(dice):
"""Rolls mixed dice and returns the sum.
- dice: List of tuples (die_size, quantity) for each die type."""
total = 0
for die_size, quantity in dice:
for _ in range(quantity):
total += random.randint(1, die_size)
return total
def convert_to_dice_notation(dice_list):
"""Converts a list of dice into a dice notation string."""
from collections import Counter
dice_counter = Counter(dice_list)
return ', '.join(f"{value}d{key}" for key, value in dice_counter.items())
def find_dice_pool(target_range):
"""Finds a combination of dice that can approximately cover a specified range of sums.
- target_range: Tuple of (min_sum, max_sum)
Returns a string representation of the dice pool."""
dice_types = [20, 12, 10, 8, 6, 4] # Available dice types, d20, d12, etc.
target_min, target_max = target_range
current_min, current_max = 0, 0
dice_pool = []
for die in dice_types:
while (current_max + die >= target_max and current_min + 1 <= target_min) or current_max < target_max:
dice_pool.append(die)
current_min += 1 # Min sum increases by 1 with the addition of each die
current_max += die # Max sum increases by the max value of the new die
if current_min >= target_min and current_max >= target_max:
break # Stop if the current range covers the target range
if current_min >= target_min and current_max >= target_max:
break # Stop if we've covered the range
# Convert the dice_pool list to a string representation
return convert_to_dice_notation(dice_pool)
# Example usage of find_dice_pool function
print(find_dice_pool((2, 12))) # Example call to find_dice_pool
print(find_dice_pool((9, 42))) # Another example call
# Simulating dice rolls with a specified dice pool
dice_pool = [(6, 4), (8, 2), (4, 1)] # Define your dice pool here
results = collections.Counter(roll_dice(dice_pool) for _ in range(10000))
# Calculating cumulative probabilities
cumulative_probabilities = {}
total_rolls = sum(results.values())
for outcome in range(min(results), max(results) + 1):
# Sum probabilities of rolling the outcome or higher
cumulative_probabilities[outcome] = sum(results[x] for x in results if x >= outcome) / total_rolls
# Printing cumulative probabilities
for outcome in sorted(cumulative_probabilities):
print(f"Probability of rolling at least {outcome}: {cumulative_probabilities[outcome]:.4f}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment