Skip to content

Instantly share code, notes, and snippets.

@nicetrysean
Created December 8, 2016 23:46
Show Gist options
  • Save nicetrysean/d2cb62b9d6da91bf07d8e4b1c645b3cc to your computer and use it in GitHub Desktop.
Save nicetrysean/d2cb62b9d6da91bf07d8e4b1c645b3cc to your computer and use it in GitHub Desktop.
Probability of hitting a target given the chance to reroll the lowest die
using System;
namespace Probability
{
internal class Program
{
private struct RollAttempt
{
public int Result;
public int[] Rolls;
}
private static Random _random;
public static void Main(string[] args)
{
_random = new Random();
int numberOfDice = AskUser("Number of dice:");
int[] number = new int[(numberOfDice * 6) + 1];
int target = AskUser("Target:");
int retries = AskUser("Rerolls:");
int iterations = 10000;
int successful = 0;
for (int i = 0; i < iterations; i++)
{
var roll = Roll(numberOfDice, target, retries);
if (roll.Result >= target)
{
successful++;
}
number[roll.Result]++;
}
Console.WriteLine($"===");
var successRate = (double)successful / iterations;
for (int index = 1; index < number.Length; index++)
{
var n = number[index];
Console.WriteLine($"{index.ToString()}: {((double)n / iterations).ToString("P")}");
}
Console.WriteLine($"===\nTarget: {target}\nDice: {numberOfDice}\nRerolls: {retries}\nTarget Surpassed: {successRate.ToString("P")}");
Console.WriteLine($"===\nPress Any Key...");
Console.ReadLine();
}
private static RollAttempt Roll(int numberOfDice, int target, int retries)
{
int[] diceResults = new int[numberOfDice];
int result = 0;
for (int i = 0; i < diceResults.Length; i++)
{
result += diceResults[i] = _random.Next(1, 7);
}
int attempt = 0;
while (result < target && attempt < retries)
{
int indexOfLowestDiceRoll = 0;
result = diceResults[indexOfLowestDiceRoll];
for (int i = 1; i < diceResults.Length; i++)
{
result += diceResults[i];
if (diceResults[indexOfLowestDiceRoll] > diceResults[i])
{
indexOfLowestDiceRoll = i;
}
}
result -= diceResults[indexOfLowestDiceRoll];
result += diceResults[indexOfLowestDiceRoll] = _random.Next(1, 7);
attempt++;
}
return new RollAttempt { Result = result, Rolls = diceResults };
}
private static int AskUser(string displayText)
{
Console.WriteLine(displayText);
int result = 0;
while (!int.TryParse(Console.ReadLine(), out result))
{
Console.WriteLine("Couldn't parse number. Try without entering any special characters or letters.");
}
return result;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment