Last active
December 29, 2023 21:25
-
-
Save Kimau/11a35e2c7d9042760b4005ef8b15354e to your computer and use it in GitHub Desktop.
Dice Rolling Probability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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