Skip to content

Instantly share code, notes, and snippets.

@Kimau
Last active December 29, 2023 21:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimau/11a35e2c7d9042760b4005ef8b15354e to your computer and use it in GitHub Desktop.
Save Kimau/11a35e2c7d9042760b4005ef8b15354e to your computer and use it in GitHub Desktop.
Dice Rolling Probability
import matplotlib.pyplot as plt
import numpy as np
def rolld20():
return np.random.randint(1, 21)
def rolld20adv():
return max(np.random.randint(1, 21),np.random.randint(1, 21))
def rolld20dis():
return min(np.random.randint(1, 21),np.random.randint(1, 21))
def rollfate():
return np.sum(np.random.randint(-1, 2, size=4))
def rollnd6(n):
return np.max(np.random.randint(1, 7, size=n))
def rollmax10(n):
return max(np.random.randint(1, 11, size=n))
def sum_two_largest_nd10(n):
if n < 2:
raise ValueError("n must be at least 2 to sum the two largest numbers")
rolls = np.random.randint(1, 11, size=n) # Roll n 10-sided dice
rolls.sort() # Sort the rolls
return rolls[-1] + rolls[-2] # Sum the two largest values
def roll_target(sides, num_die, target, explode=False):
results = np.random.randint(1, sides + 1, size=num_die) # Roll num_die dice with sides
def adjust_result(result):
if result == 1:
return -1
elif result >= target:
return 1
else:
return 0
total = np.sum([adjust_result(result) for result in results])
if explode:
num_explode_die = np.count_nonzero(results == sides) # Count the number of results equal to sides
if num_explode_die > 0:
exploded_total = roll_target(sides, num_explode_die, target, explode=True)
total += exploded_total
return total
def propCurve(dice_func, num_rolls):
results = [dice_func() for _ in range(num_rolls)]
unique_results, counts = np.unique(results, return_counts=True)
return unique_results, counts
def propCurveVar(dice_func, num_rolls, dice_var):
results = [dice_func(dice_var) for _ in range(num_rolls)]
unique_results, counts = np.unique(results, return_counts=True)
return unique_results, counts
def propCurveTarget(num_rolls, sides, num_die, target, explode=False):
results = [roll_target(sides, num_die, target, explode) for _ in range(num_rolls)]
unique_results, counts = np.unique(results, return_counts=True)
return unique_results, counts
def plot_save(desc, filename):
plt.xlabel('Result')
plt.ylabel('Frequency')
plt.title(desc)
plt.legend()
plt.savefig(filename)
plt.show()
plt.figure()
def main():
num_rolls = 100000
plt.figure()
if False: # D20
unique_results, counts = propCurve(rolld20, num_rolls)
plt.plot(unique_results, counts, color='red', label='Rolld20')
unique_results, counts = propCurve(rolld20adv, num_rolls)
plt.plot(unique_results, counts, color='green', label='Rolld20Adv')
unique_results, counts = propCurve(rolld20dis, num_rolls)
plt.plot(unique_results, counts, color='blue', label='Rolld20Dis')
plot_save("d20", "dice_d20.png")
if False: # Fate
unique_results, counts = propCurve(rollfate, num_rolls)
plt.plot(unique_results, counts, color='black', label='RollFate')
plot_save("Fate Dice", "dice_fate.png")
if False: # nd6
unique_results, counts = propCurveVar(rollnd6, num_rolls, 2)
plt.plot(unique_results, counts, color='red', label='Roll2d6')
unique_results, counts = propCurveVar(rollnd6, num_rolls, 4)
plt.plot(unique_results, counts, color='green', label='Roll4d6')
unique_results, counts = propCurveVar(rollnd6, num_rolls, 10)
plt.plot(unique_results, counts, color='blue', label='Roll10d6')
plot_save("Sum D6", "dice_sum_d6.png")
if True: # Roll max 10
colors = ["#FF0000","#FF7F00","#FFFF00","#00FF00","#0000FF"]
for i, col in enumerate(colors):
num_die = (i*2)+1
unique_results, counts = propCurveVar(rollmax10, num_rolls, num_die)
plt.plot(unique_results, counts, color=col, label=f'Roll {num_die}d10')
plot_save("Max D10", "dice_max_d10.png")
if True: # Roll max 10 sum2
colors = ["#FF0000","#FF7F00","#FFFF00","#00FF00","#0000FF"]
for i, col in enumerate(colors):
num_die = (i*2)+2
unique_results, counts = propCurveVar(sum_two_largest_nd10, num_rolls, num_die)
plt.plot(unique_results, counts, color=col, label=f'Roll {num_die}d10')
plot_save("Sum Max 2D10", "dice_summax_2d10.png")
if False: # D10 Target Explode vs Not
# First, plot with explode=False and slightly darker colors
sides = 10
target = 6
rolls = [1, 3, 5, 7, 10]
explode = False
colors = ['darkred', 'darkorange', 'darkgoldenrod', 'darkgreen', 'darkblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides}')
# Then, plot with explode=True and slightly brighter colors
explode = True
colors = ['red', 'orange', 'gold', 'limegreen', 'dodgerblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
plot_save("D10 Target Explode vs Not", "dice_target_d10.png")
if False: # D6 Target Explode vs Not
# First, plot with explode=False and slightly darker colors
sides = 6
target = 4
rolls = [1, 3, 5, 7, 10]
explode = False
colors = ['darkred', 'darkorange', 'darkgoldenrod', 'darkgreen', 'darkblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides}')
# Then, plot with explode=True and slightly brighter colors
explode = True
colors = ['red', 'orange', 'gold', 'limegreen', 'dodgerblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
plot_save("D6 Target Explode vs Not", "dice_target_d6.png")
if False: # D6 Target with vary Target number (always explode)
sides = 6
explode = True
rolls = [1, 3, 5, 7, 10]
target = 3
colors = ['darkred', 'darkorange', 'darkgoldenrod', 'darkgreen', 'darkblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
colors = ['red', 'orange', 'gold', 'limegreen', 'dodgerblue']
target = 4
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
colors = ['#FF6666', '#FFB266', '#FFD700', '#CCFF99', '#ADD8E6']
target = 5
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
plot_save("D6 Target with vary Target number (always explode)", "dice_target_d6_shift.png")
if False: # D10 Target with vary Target number (always explode)
sides = 10
explode = True
rolls = [1, 3, 5, 7, 10]
target = 5
colors = ['darkred', 'darkorange', 'darkgoldenrod', 'darkgreen', 'darkblue']
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
colors = ['red', 'orange', 'gold', 'limegreen', 'dodgerblue']
target = 6
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
colors = ['#FF6666', '#FFB266', '#FFD700', '#CCFF99', '#ADD8E6']
target = 7
for i, num_die in enumerate(rolls):
unique_results, counts = propCurveTarget(num_rolls, 10, num_die, target, explode)
plt.plot(unique_results, counts, color=colors[i], label=f'Target {target} {num_die}d{sides} (Explode)')
plot_save("D10 Target with vary Target number (always explode)", "dice_target_d10_shift.png")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment