import numpy as np
def RollD6():
return np.random.randint(1,7)
def RollD6():
return np.random.randint(1,7)
def RollNDice(n):
diceValues = np.random.randint(1,7,n)
return diceValues
def Roll3D6():
return sum(RollNDice(3))
def Roll4D6D1():
rolls = RollNDice(4)
rolls = np.delete(rolls, rolls.argmin()) # delete lowest value
return sum(rolls)
PointBuyValue = {
3: -9,
4: -6,
5: -4,
6: -2,
7: -1,
8: 0,
9: 1,
10: 2,
11: 3,
12: 4,
13: 5,
14: 7,
15: 9,
16: 12,
17: 15,
18: 19
}
def RollStats4D6D1():
stats = []
for i in range(6):
stats.append(Roll4D6D1())
return stats
def RollStats3D6(drop):
stats = []
for stat in range(6+drop):
stats.append(Roll3D6())
stats.sort()
for i in range(drop):
stats.pop(0)
return stats
def CalculatePointBuy(stats):
pointBuyTotal = 0
for stat in stats:
pointBuyTotal = pointBuyTotal + PointBuyValue[stat]
return pointBuyTotal
def Choose4D6D1():
pb_max = 0
for i in range(4):
pb = CalculatePointBuy(RollStats4D6D1())
if pb > pb_max:
pb_max = pb
return pb_max
def Choose3D6(drop):
pb_max = 0
for i in range(4):
pb = CalculatePointBuy(RollStats3D6(drop))
if pb > pb_max:
pb_max = pb
return pb_max
np.random.seed(42)
n_sims = 1000
record_4d6d1 = []
record_3d6 = []
record_pick4d6d1 = []
record_pick3d6 = []
for runs in range(n_sims):
record_4d6d1.append(CalculatePointBuy(RollStats4D6D1()))
record_3d6.append(CalculatePointBuy(RollStats3D6(1)))
record_pick4d6d1.append(Choose4D6D1())
record_pick3d6.append(Choose3D6(1))
print ("Average Point buy (4d6d1): %.2f" % (np.sum(record_4d6d1)/n_sims))
print ("Average Point buy (3d6): %.2f" % (np.sum(record_3d6)/n_sims))
print ("Average Point buy (Choose 4d6d1): %.2f" %
(np.sum(record_pick4d6d1)/n_sims))
print ("Average Point buy (Choose 3d6): %.2f" %
(np.sum(record_pick3d6)/n_sims))
ax = sns.distplot(record_4d6d1)
plt.title("Histogram of %d simulated rolls" % n_sims)
ax.set_xlabel("Point Buy Total")
ax.set_ylabel("Count")
sns.distplot(record_3d6)
sns.distplot(record_pick4d6d1)
sns.distplot(record_pick3d6)
plt.legend(labels=['4d6d1', '3d6', 'Choose 4d6d1', 'Choose 3d6'])
aW1wb3J0IG51bXB5IGFzIG5wCgpkZWYgUm9sbEQ2KCk6CiAgICByZXR1cm4gbnAucmFuZG9tLnJhbmRpbnQoMSw3KQoKZGVmIFJvbGxENigpOgogICAgcmV0dXJuIG5wLnJhbmRvbS5yYW5kaW50KDEsNykKCmRlZiBSb2xsTkRpY2Uobik6CiAgICBkaWNlVmFsdWVzID0gbnAucmFuZG9tLnJhbmRpbnQoMSw3LG4pCiAgICByZXR1cm4gZGljZVZhbHVlcwogICAgCmRlZiBSb2xsM0Q2KCk6CiAgICByZXR1cm4gc3VtKFJvbGxORGljZSgzKSkKCmRlZiBSb2xsNEQ2RDEoKToKICAgIHJvbGxzID0gUm9sbE5EaWNlKDQpCiAgICByb2xscyA9IG5wLmRlbGV0ZShyb2xscywgcm9sbHMuYXJnbWluKCkpICMgZGVsZXRlIGxvd2VzdCB2YWx1ZQogICAgcmV0dXJuIHN1bShyb2xscykKICAgIApQb2ludEJ1eVZhbHVlID0gewogICAgMzogLTksCiAgICA0OiAtNiwKICAgIDU6IC00LAogICAgNjogLTIsCiAgICA3OiAtMSwKICAgIDg6IDAsCiAgICA5OiAxLAogICAgMTA6IDIsCiAgICAxMTogMywKICAgIDEyOiA0LAogICAgMTM6IDUsCiAgICAxNDogNywKICAgIDE1OiA5LAogICAgMTY6IDEyLAogICAgMTc6IDE1LAogICAgMTg6IDE5Cn0KCmRlZiBSb2xsU3RhdHM0RDZEMSgpOgogICAgc3RhdHMgPSBbXQogICAgZm9yIGkgaW4gcmFuZ2UoNik6CiAgICAgICAgc3RhdHMuYXBwZW5kKFJvbGw0RDZEMSgpKQogICAgcmV0dXJuIHN0YXRzCgpkZWYgUm9sbFN0YXRzM0Q2KGRyb3ApOgogICAgc3RhdHMgPSBbXQogICAgZm9yIHN0YXQgaW4gcmFuZ2UoNitkcm9wKToKICAgICAgICBzdGF0cy5hcHBlbmQoUm9sbDNENigpKQogICAgc3RhdHMuc29ydCgpCiAgICBmb3IgaSBpbiByYW5nZShkcm9wKToKICAgIAlzdGF0cy5wb3AoMCkKICAgIHJldHVybiBzdGF0cwoKZGVmIENhbGN1bGF0ZVBvaW50QnV5KHN0YXRzKToKICAgIHBvaW50QnV5VG90YWwgPSAwCiAgICBmb3Igc3RhdCBpbiBzdGF0czoKICAgICAgICBwb2ludEJ1eVRvdGFsID0gcG9pbnRCdXlUb3RhbCArIFBvaW50QnV5VmFsdWVbc3RhdF0KICAgIHJldHVybiBwb2ludEJ1eVRvdGFsCiAgICAKZGVmIENob29zZTRENkQxKCk6CiAgICBwYl9tYXggPSAwCiAgICBmb3IgaSBpbiByYW5nZSg0KToKICAgICAgICBwYiA9IENhbGN1bGF0ZVBvaW50QnV5KFJvbGxTdGF0czRENkQxKCkpCiAgICAgICAgaWYgcGIgPiBwYl9tYXg6CiAgICAgICAgICAgIHBiX21heCA9IHBiCiAgICByZXR1cm4gcGJfbWF4CgoKZGVmIENob29zZTNENihkcm9wKToKICAgIHBiX21heCA9IDAKICAgIGZvciBpIGluIHJhbmdlKDQpOgogICAgICAgIHBiID0gQ2FsY3VsYXRlUG9pbnRCdXkoUm9sbFN0YXRzM0Q2KGRyb3ApKQogICAgICAgIGlmIHBiID4gcGJfbWF4OgogICAgICAgICAgICBwYl9tYXggPSBwYgogICAgcmV0dXJuIHBiX21heAoKbnAucmFuZG9tLnNlZWQoNDIpCgpuX3NpbXMgPSAxMDAwCnJlY29yZF80ZDZkMSA9IFtdCnJlY29yZF8zZDYgPSBbXQpyZWNvcmRfcGljazRkNmQxID0gW10KcmVjb3JkX3BpY2szZDYgPSBbXQoKZm9yIHJ1bnMgaW4gcmFuZ2Uobl9zaW1zKToKICAgIHJlY29yZF80ZDZkMS5hcHBlbmQoQ2FsY3VsYXRlUG9pbnRCdXkoUm9sbFN0YXRzNEQ2RDEoKSkpCiAgICByZWNvcmRfM2Q2LmFwcGVuZChDYWxjdWxhdGVQb2ludEJ1eShSb2xsU3RhdHMzRDYoMSkpKQogICAgcmVjb3JkX3BpY2s0ZDZkMS5hcHBlbmQoQ2hvb3NlNEQ2RDEoKSkKICAgIHJlY29yZF9waWNrM2Q2LmFwcGVuZChDaG9vc2UzRDYoMSkpCgpwcmludCAoIkF2ZXJhZ2UgUG9pbnQgYnV5ICg0ZDZkMSk6ICUuMmYiICUgKG5wLnN1bShyZWNvcmRfNGQ2ZDEpL25fc2ltcykpCnByaW50ICgiQXZlcmFnZSBQb2ludCBidXkgKDNkNik6ICUuMmYiICUgKG5wLnN1bShyZWNvcmRfM2Q2KS9uX3NpbXMpKQpwcmludCAoIkF2ZXJhZ2UgUG9pbnQgYnV5IChDaG9vc2UgNGQ2ZDEpOiAlLjJmIiAlCiAgICAgICAgKG5wLnN1bShyZWNvcmRfcGljazRkNmQxKS9uX3NpbXMpKQpwcmludCAoIkF2ZXJhZ2UgUG9pbnQgYnV5IChDaG9vc2UgM2Q2KTogJS4yZiIgJQogICAgICAgIChucC5zdW0ocmVjb3JkX3BpY2szZDYpL25fc2ltcykpCgpheCA9IHNucy5kaXN0cGxvdChyZWNvcmRfNGQ2ZDEpCnBsdC50aXRsZSgiSGlzdG9ncmFtIG9mICVkIHNpbXVsYXRlZCByb2xscyIgJSBuX3NpbXMpCmF4LnNldF94bGFiZWwoIlBvaW50IEJ1eSBUb3RhbCIpCmF4LnNldF95bGFiZWwoIkNvdW50IikKCnNucy5kaXN0cGxvdChyZWNvcmRfM2Q2KQpzbnMuZGlzdHBsb3QocmVjb3JkX3BpY2s0ZDZkMSkKc25zLmRpc3RwbG90KHJlY29yZF9waWNrM2Q2KQpwbHQubGVnZW5kKGxhYmVscz1bJzRkNmQxJywgJzNkNicsICdDaG9vc2UgNGQ2ZDEnLCAnQ2hvb3NlIDNkNiddKQ==