Search code examples
javaprobabilitydice

Dice Sum Probability with Different types of Dice


I am currently working on a java application where I need to calculate the probabilities of rolling each sum for a variety of dice. The dice types I am supporting are d4 (4 sided dice), d6 (6 sided dice), d8 (8 sided dice), d10, d12, and d20. The user will be able to input the number of each type of dice they want to use in the calculation. For example, a user may enter 6 d6 and 4 d4.

With this given information (the number of dice of each type), I am looking to calculate the probability that each possible sum could be rolled. I will then be using this information to create a chart showing the probability distribution from the selected combination of dice provided.

This application is being written in Java.

Where I am currently at is I have a function that will calculate the probability of a specific sum for a using only one size of dice

/*
    Recursively calculates the probability of rolling a particular number
    when rolling multiple dice of one type
    @param dice Number of dice
    @param seekedValue Value whose probability is being calculated
    @param sides Number of sides on the type of die
     */
    private double diceProb(int dice, int seekedValue, int sides){
        if (dice == 0){
            if (seekedValue == 0){
                return 1.0;
            } else {
                return 0.0;
            }
        } else {
            double sum = 0;
            for (int i = seekedValue - sides; i < seekedValue; i++){
                sum += diceProb(dice -1, i, sides) / sides;
            }
            return sum;
        }

    }

I then use this code to find all the possible probabilites

/*
Variable Explanations:
diceEntries: This array list contains the number of each dice supplied by the user.
It is ordered by number of sides, with d4 at the beginning and d20 at the end
diceValues: This array contains the sides of the dice types
probArray: this array list will contain the probabilities of each sum possible
min: the minimum sum  possible
max: the maximum sum possible
*/
ArrayList<Integer> diceEntries
ArrayList<Float> probArray = new ArrayList<>();
int[] diceValues = {4,6,8,10,12,20};
float prob = 0;
for (int i = min; i <= max; i++){
    for (int j = 0; j <= 5; j++) {
        prob = (float) diceProb(diceEntries.get(j), i, diceValues[j]);
        if (prob != 0) {
            probArray.add(prob);
        }
    }
}

My current code is only able to handle dice of one size, ie only d6s or d4s and not a mix of them.

If the community can provide some guidance, it would be greatly appreciated. I am open to over approaches as well. For example, I have read that generating functions might be a better way of doing this, but my combinatorics statistics are a bit weak and if someone did have a way of coding that up, it would nice to see it.

Thanks a lot folks


Solution

  • Another entry for the brute force method, using a list of Integers(dice sides) to handle multiple die types. The advantage is that if you want a lot of probabilities, you can run it once then just query the various probabilities. The disadvantage is that as a brute force method it's very inefficient for just getting a single probability.

    public int[] probs;
    
    public void genRolls(int sum, List<Integer> sides)
    {
        if (sides.size() == 0)
        {
            probs[sum]++;
            return;
        }
        int top = sides.get(0);
        for (int x = 1; x <= top; x++)
            genRolls(sum+x, sides.subList(1, sides.size()));
    }
    
    public void diceprob(int target, List<Integer> sides)
    {
        int maxval = 0;
        double possibilities = 1;
        for (Integer i : sides)
        {
            maxval+= i;
            possibilities *= i;
        }
        probs = new int[maxval+1];
        genRolls(0, sides);
        System.out.println("Probability is " + (probs[target]/possibilities));
    }