The following examples and translations are intended to showcase dyce’s flexibility.
If you have exposure to another tool, they may also help with transition.
>>>fromdyceimportH,P>>>p_4d6=4@P(6)>>>res1=p_4d6.h(slice(1,None))# discard the lowest die (index 0)>>>d6_reroll_first_one=H(6).substitute(lambdah,outcome:H(6)ifoutcome==1elseoutcome)>>>p_4d6_reroll_first_one=(4@P(d6_reroll_first_one))>>>res2=p_4d6_reroll_first_one.h(slice(1,None))# discard the lowest>>>p_4d6_reroll_all_ones=4@P(H((2,3,4,5,6)))>>>res3=p_4d6_reroll_all_ones.h(slice(1,None))# discard the lowest
Visualization:
1 2 3 4 5 6 7 8 910111213141516171819
>>>importmatplotlib# doctest: +SKIP>>>matplotlib.pyplot.plot(...*res1.distribution_xy(),...marker=".",...label="Discard lowest",...)# doctest: +SKIP>>>matplotlib.pyplot.plot(...*res2.distribution_xy(),...marker=".",...label="Re-roll first 1; discard lowest",...)# doctest: +SKIP>>>matplotlib.pyplot.plot(...*res3.distribution_xy(),...marker=".",...label="Re-roll all 1s; discard lowest",...)# doctest: +SKIP>>>matplotlib.pyplot.legend()# doctest: +SKIP>>>matplotlib.pyplot.title(r"Comparing various take-three-of-4d6 methods")# doctest: +SKIP>>>matplotlib.pyplot.show()# doctest: +SKIP
>>>single_attack=2@H(6)+5>>>defgwf(h:H,outcome):...returnhifoutcomein(1,2)elseoutcome>>>great_weapon_fighting=2@(H(6).substitute(gwf))+5# reroll either die if it is a one or two>>>print(single_attack.format(width=0)){...,7:2.78%,8:5.56%,9:8.33%,10:11.11%,11:13.89%,12:16.67%,13:13.89%,...}>>>print(great_weapon_fighting.format(width=0)){...,7:0.31%,8:0.62%,9:2.78%,10:4.94%,11:9.88%,12:14.81%,13:17.28%,...}
>>>importmatplotlib# doctest: +SKIP>>>matplotlib.pyplot.plot(*res.distribution_xy(),marker=".")# doctest: +SKIP>>>matplotlib.pyplot.title(r"Modeling taking the three highest of ten exploding d10s")# doctest: +SKIP>>>matplotlib.pyplot.show()# doctest: +SKIP
function: dupes in DICE:s {
D: 0
loop X over {2..#DICE} {
if ((X-1)@DICE = X@DICE) { D: D + 1}
}
result: D
}
Translation:
1 2 3 4 5 6 7 8 910
>>>defdupes(p:P):...forroll,countinp.rolls_with_counts():...dupes=0...foriinrange(1,len(roll)):...# Outcomes are ordered, so we only have to look at one neighbor...ifroll[i]==roll[i-1]:...dupes+=1...yielddupes,count>>>res=H(dupes(8@P(10)))
Visualization:
1234567
>>>fromdyce.vizimportplot_burst>>>plot_burst(...res,...desc=r"Chances of rolling $n$ duplicates in 8d10",...)# doctest: +SKIP>>>matplotlib.pyplot.tight_layout()# doctest: +SKIP>>>matplotlib.pyplot.show()# doctest: +SKIP
function: brawl A:s vs B:s {
SA: A >= 1@B
SB: B >= 1@A
if SA-SB=0 {
result:(A > B) - (A < B)
}
result:SA-SB
}
output [brawl 3d6 vs 3d6] named "A vs B Damage"
function: set element I:n in SEQ:s to N:n {
NEW: {}
loop J over {1 .. #SEQ} {
if I = J { NEW: {NEW, N} }
else { NEW: {NEW, J@SEQ} }
}
result: NEW
}
function: brawl A:s vs B:s with optional swap {
if #A@A >= 1@B {
result: [brawl A vs B]
}
AX: [sort [set element #A in A to 1@B]]
BX: [sort [set element 1 in B to #A@A]]
result: [brawl AX vs BX]
}
output [brawl 3d6 vs 3d6 with optional swap] named "A vs B Damage"