And finally, here are two charts for the average damage dealt by opposed rolls, assuming a DX of 1. This first one rounds the averages to the nearest hundredth, while the second one rounds them to the nearest whole number.

As promised, here is the source code for the program I used to make all the charts except the difficulty chart. It is written in Python.

Code: Select all

```
## -*- coding: utf-8 -*-
## This program simulates the rolling of dice and
## determines the highest matched set.
import random
## A dice cup is a group of dice to be
## rolled and evaluated.
class DiceCup:
## Specify the number of sides per die
## and the number of dice. Default is
## two six-sided dice.
def __init__ (self):
pass
## Make a roll of a certain number and type
## of dice.
def rollDice (self, amount=2, sides=6):
## This list will contain the
## counts for each roll.
## Default is six sides.
rollTotals = []
## Put the appropriate number of
## sides to be counted.
for i in range(0, sides):
rollTotals.append(0)
## Roll the specified number of dice.
## Count how many of each roll there
## is.
for i in range(0, amount):
## Roll a die.
roll = random.randint(0,sides-1)
## Tally the result.
rollTotals[roll] += 1
## Make a new list for the values
## of the matched sets.
matchedSets = []
## Multiply the tallies by the
## value of their rolls.
for i in range(0, sides):
matchedSets.append(rollTotals[i] * (i+1))
## Put the tallies of the matched set
## in a string.
indicator = str(rollTotals)
matchedIndicator = str(matchedSets)
## Grab the matched sets' highest
## value.
val = max(matchedSets)
## Print the result.
# result = "%s: %d" % (indicator, val)
result = ["%s: %d" % (matchedIndicator, val), val]
return result
dc = DiceCup()
## Roll results are output based
## on the value of the matched
## sets rather than the roll totals.
## The order is as follows:
## [Ones, Twos, Threes, Fours, Fives, Sixes]
## To run one of the code blocks below,
## remove the triple quotes. I recommend
## releasing only one block at a time.
## This code simulates a number of rolls against
## an arbitrary difficulty number and outputs
## the percentage of success. Optionally, it
## prints the winning rolls.
"""
rollWins = 0
totalRollNum = 50000
rollDiceAmt = 2
difficulty = 6
for i in range(0, totalRollNum):
whatRoll = dc.rollDice(rollDiceAmt, 6)
if whatRoll[1] >= difficulty:
# print("{0} beats difficulty {1}".format(whatRoll[0], difficulty))
rollWins += 1
percentage = 100 * (1.0 * rollWins / totalRollNum)
print("{0} dice against difficulty number {1}:".format(rollDiceAmt, difficulty))
print("Win probability: {0}".format(percentage))
"""
## This code simulates a number of rolls against
## an arbitrary difficulty number and outputs
## the percentage of success. It also tests
## the rolls against a sequence of difficulty
## numbers.
"""
for i in range(6, 26, 2):
rollWins = 0
totalRollNum = 50000
rollDiceAmt = 10
difficulty = i
for i in range(0, totalRollNum):
whatRoll = dc.rollDice(rollDiceAmt, 6)
if whatRoll[1] >= difficulty:
rollWins += 1
percentage = 100 * (1.0 * rollWins / totalRollNum)
print("{0} dice against difficulty number {1}:".format(rollDiceAmt, difficulty))
print("Win probability: {0}\n".format(percentage))
"""
## This code simulates an arbitrary number
## of opposed rolls and outputs the percentage
## of success if it exceeds the defending roll.
## It also optionally prints winning rolls;
## this is useful if you want to check out
## unusual results such as rolls of two dice
## beating rolls of seventeen dice.
"""
rollWins = 0
totalRollNum = 50000
rollOneAmt = 2
rollTwoAmt = 17
for i in range(0, totalRollNum):
rollOne = dc.rollDice(rollOneAmt, 6)
rollTwo = dc.rollDice(rollTwoAmt, 6)
if rollOne[1] > rollTwo[1]:
# print("{0} to {1}".format(rollOne[0], rollTwo[0]))
rollWins += 1
percentage = 100 * (1.0 * rollWins / totalRollNum)
print("{0} dice against {1} dice:".format(rollOneAmt, rollTwoAmt))
print("Win probability: {0}".format(percentage))
"""
## This code simulates an arbitrary number
## of opposed rolls and outputs the percentage
## of success. Unlike the above, it tests
## numbers of defending dice in sequence.
"""
for i in range(2, 25):
rollWins = 0
totalRollNum = 50000
rollOneAmt = 2
rollTwoAmt = i
for j in range(0, totalRollNum):
rollOne = dc.rollDice(rollOneAmt, 6)
rollTwo = dc.rollDice(rollTwoAmt, 6)
if rollOne[1] > rollTwo[1]:
rollWins += 1
percentage = 100 * (1.0 * rollWins / totalRollNum)
print("{0} dice against {1} dice:".format(rollOneAmt, rollTwoAmt))
print("Win probability: {0}\n".format(percentage))
"""
## This code simulates an arbitrary number
## of opposed rolls and averages the damage
## from the attacker's point of view using a DX of 1;
## this means that defense rolls that match or exceed
## the attacking roll will return values of zero.
## The averages will be decimals.
## It also optionally prints winning rolls.
"""
damageSum = 0
damageMultiplier = 1
totalRollNum = 50000
rollOneAmt = 2
rollTwoAmt = 2
for i in range(0, totalRollNum):
rollOne = dc.rollDice(rollOneAmt, 6)
rollTwo = dc.rollDice(rollTwoAmt, 6)
rollDiff = rollOne[1] - rollTwo[1]
if rollDiff < 0:
rollDiff = 0
# if rollOne[1] > rollTwo[1]:
# print("{0} to {1}".format(rollOne[0], rollTwo[0]))
damageSum += rollDiff * damageMultiplier
avgDamage = 1.0 * damageSum / totalRollNum
print("{0} dice against {1} dice:".format(rollOneAmt, rollTwoAmt))
print("Average damage (DX {0}): {1}".format(damageMultiplier, avgDamage))
"""
## This code simulates an arbitrary number
## of opposed rolls and averages the damage
## from the attacker's point of view using a DX of 1;
## this means that defense rolls that match or exceed
## the attacking roll will return values of zero.
## The averages will be decimals.
## It tests numbers of defending dice in sequence.
"""
for i in range(2, 25):
damageSum = 0
damageMultiplier = 1
totalRollNum = 50000
rollOneAmt = 24
rollTwoAmt = i
for i in range(0, totalRollNum):
rollOne = dc.rollDice(rollOneAmt, 6)
rollTwo = dc.rollDice(rollTwoAmt, 6)
rollDiff = rollOne[1] - rollTwo[1]
if rollDiff < 0:
rollDiff = 0
# if rollOne[1] > rollTwo[1]:
# print("{0} to {1}".format(rollOne[0], rollTwo[0]))
damageSum += rollDiff * damageMultiplier
avgDamage = 1.0 * damageSum / totalRollNum
print("{0} dice against {1} dice:".format(rollOneAmt, rollTwoAmt))
print("Average damage (DX {0}): {1}\n".format(damageMultiplier, avgDamage))
"""
```