public class Program
{
public static void Main()
{
Random rng = new Random();
Console.WriteLine("\nEasy challenge (DC = 15)\n");
tryChallenge(100000, 5, 15, 12, 6, rng);
tryChallenge(100000, 6, 15, 12, 6, rng);
tryChallenge(100000, 7, 15, 12, 6, rng);
tryChallenge(100000, 8, 15, 12, 6, rng);
Console.WriteLine("\nModerate challenge (DC = 19)\n");
tryChallenge(100000, 7, 19, 12, 6, rng);
tryChallenge(100000, 9, 19, 12, 6, rng);
tryChallenge(100000, 11, 19, 12, 6, rng);
tryChallenge(100000, 12, 19, 12, 6, rng);
tryChallenge(100000, 13, 19, 12, 6, rng);
Console.WriteLine("\nHard challenge (DC = 23)\n");
tryChallenge(100000, 9, 23, 12, 6, rng);
tryChallenge(100000, 11, 23, 12, 6, rng);
tryChallenge(100000, 13, 23, 12, 6, rng);
tryChallenge(100000, 15, 23, 12, 6, rng);
tryChallenge(100000, 16, 23, 12, 6, rng);
}
private static void tryChallenge
(
int numTrials,
int skill,
int dc,
int requiredSuccesses,
int maxFailures,
Random rng
)
{
double successRatio = successRate
(
numTrials,
skill,
dc,
requiredSuccesses,
maxFailures,
rng
);
double percentSuccess = 100 * successRatio;
Console.WriteLine
(
string.Format
(
"Skill = {0}, DC = {1}, %success = {2:f2}",
skill, dc, percentSuccess
)
);
}
private static double successRate
(
int numTrials,
int skill,
int dc,
int requiredSuccesses,
int maxFailures,
Random rng
)
{
int totalSuccesses = 0;
for (int i = 0; i < numTrials; ++i)
{
if (attemptChallenge(skill, dc, requiredSuccesses, maxFailures, rng))
{
++totalSuccesses;
}
}
return ((double)totalSuccesses)/numTrials;
}
private static bool attemptChallenge
(
int skill,
int dc,
int requiredSuccesses,
int maxFailures,
Random rng
)
{
int successes = 0;
int failures = 0;
for (;;)
{
// Note: rng.Next(x) returns number from 0..(x-1).
// So we must add 1 to it to get 1..x.
int skillRoll = skill + 1 + rng.Next(20);
if (skillRoll >= dc) // Succeeded?
{
if (++successes >= requiredSuccesses)
{
return true;
}
}
else // Failed.
{
if (++failures >= maxFailures)
{
return false;
}
}
}
}
}