import java.util.Arrays;
import java.util.Random;
public class Main {
public static void main(String[] args) {
new Main().testDice();
}
private int roll20(Random rand) {
return rand.nextInt(20) + 1;
}
private class TestResults {
final String name;
final double averageRoll;
final int modeRoll;
final int medianRoll;
final double variance;
final int low;
final int high;
double standardDeviation() {
return Math.sqrt(variance);
}
public TestResults(String name, int[] rolls) {
this.name = name;
Arrays.sort(rolls);
int median = rolls[rolls.length / 2];
int iAverage = 0;
int[] outcomes = new int[20];
Arrays.fill(outcomes, 0);
for(int roll : rolls) {
iAverage += roll;
outcomes[roll - 1]++;
}
averageRoll = iAverage / (double)rolls.length;
double dVariance = 0;
for(int roll : rolls) {
dVariance += Math.pow(roll - averageRoll, 2);
}
dVariance /= rolls.length;
int max = 0;
int maxRoll = 0;
for(int i = 0; i < outcomes.length; i++) {
if(outcomes[i] > max) {
maxRoll = i;
max = outcomes[i];
}
}
modeRoll = maxRoll + 1;
medianRoll = median;
variance = dVariance;
low = rolls[(int)(rolls.length * 0.025)];
high = rolls[(int)(rolls.length * 0.975)];
}
void print() {
System.out.println("ResultSet: " + name);
System.out.println(toString());
}
public String toString() {
String out = "";
out += " " + "Average: " + averageRoll + "\n";
out += " " + "Variance: " + variance + "\n";
out += " " + "Std. Deviation: " + standardDeviation() + "\n";
out += " " + "95% range: [" + low + ", " + high + "]\n";
out += " " + "Mode: " + modeRoll + "\n";
out += " " + "Median: " + medianRoll + "\n";
return out;
}
}
private TestResults normal(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
rolls[i] = roll;
}
return new TestResults("Normal", rolls);
}
private TestResults advantage(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
int roll2 = roll20(rand);
roll = Math.max(roll, roll2);
rolls[i] = roll;
}
return new TestResults("Advantage", rolls);
}
private TestResults disadvantage(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
int roll2 = roll20(rand);
roll = Math.min(roll, roll2);
rolls[i] = roll;
}
return new TestResults("Disadvantage", rolls);
}
private TestResults advantage2(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
int roll2 = roll20(rand);
int roll3 = roll20(rand);
roll = Math.max(Math.max(roll, roll2), roll3);
rolls[i] = roll;
}
return new TestResults("Double Advantage", rolls);
}
private TestResults disadvantage2(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
int roll2 = roll20(rand);
int roll3 = roll20(rand);
roll = Math.min(Math.min(roll, roll2), roll3);
rolls[i] = roll;
}
return new TestResults("Double Disadvantage", rolls);
}
private TestResults advantage2alt(int trials) {
Random rand = new Random();
int[] rolls = new int[trials];
for(int i = 0; i < rolls.length; i++) {
int roll = roll20(rand);
int roll2 = roll20(rand);
if(roll < roll2) {
roll = roll20(rand);
} else {
roll2 = roll20(rand);
}
roll = Math.max(roll, roll2);
rolls[i] = roll;
}
return new TestResults("Alternate Double Advantage", rolls);
}
public void testDice() {
TestResults[] results = new TestResults[]{
normal(1_000_000),
advantage(1_000_000),
disadvantage(1_000_000),
advantage2(1_000_000),
disadvantage2(1_000_000),
advantage2alt(1_000_000),
};
for(TestResults result : results) {
result.print();
}
}
}