Alright, so I am simulating a rice roll 100 times, repeatedly.
It's getting some whack numbers for some reason, I can't find the problem in code. I have done some printing of the different variables and it seems fine, but I know theres something wrong.

package com.github.geodox.dicerollingstats.main;

import java.util.Arrays;
import java.util.Random;

/**
 * @author GeoDoX
 *
 * RollingStats.java
 */
public class RollingStats
{
    private static Random rand; //Used for generating the roll
    private static int[] rolls; //Stores the roll counts
    private static int[] highestRolls; //Stores the highest roll counts

    public static void main(String[] args)
    {
        rand = new Random();
        rolls = new int[6]; //new int array of size 6
        highestRolls = new int[6]; //new int array of size 6
        rollConsec();
    }

    private static int[] roll()
    {
        for(int i = 1; i <= 100; i++) //Roll 100 Times
        {
            int diceValue = rand.nextInt(6) + 1; //Generate number between 1 - 6

            rolls[diceValue - 1] = rolls[diceValue - 1] += 1; //Add 1 to the Array at the index of the roll
        }

        return rolls;
    }

    private static void rollConsec()
    {
        while(true) //Keep repeating
        {
            int[] tempArray = roll();
            int currHighest = 0; //Value to store the highest number;
            int highestIndex = 0; //Value to store the highest index, 1 - 6

            for(int i = 1; i < 6; i++) //Get highest index
            {
                int currValue = 0;

                currValue = tempArray[i]; //Set currValue equal to the value at i

                if(currValue > currHighest) //Check if currValue is higher then the currently highest
                {
                    currHighest = currValue; //If it is, set the highest to the current value
                    highestIndex = i; //Set the highest index to i
                }
            }

            highestRolls[highestIndex - 1] = highestRolls[highestIndex - 1] += 1; //Add 1 to the highest index, represents the highest roll out of the 100 inital dice rolls
            System.out.println(Arrays.toString(highestRolls)); //Print the array
        }
    }

}

Example Output after 10 seconds:

...
[73695, 13823, 330563, 5799, 19362, 0]
[73696, 13823, 330563, 5799, 19362, 0]
[73697, 13823, 330563, 5799, 19362, 0]
[73698, 13823, 330563, 5799, 19362, 0]
[73699, 13823, 330563, 5799, 19362, 0]
[73700, 13823, 330563, 5799, 19362, 0]
[73701, 13823, 330563, 5799, 19362, 0]
[73702, 13823, 330563, 5799, 19362, 0]
[73703, 13823, 330563, 5799, 19362, 0]
[73704, 13823, 330563, 5799, 19362, 0]
[73705, 13823, 330563, 5799, 19362, 0]

Any help is appreciated.

Dani AI

Generated

Brief summary and practical notes based on the thread: the original "weird" output came from a few simple mistakes that were spotted in replies by and then confirmed by . Key problems were (a) the double/incorrect assignment to the same array element, (b) using a shared class-level counts array so results accumulated across runs, and (c) an off‑by‑one / loop-indexing issue when scanning for the maximum. correctly noted that ties need a policy (report all ties or pick one). The code changes described later (making the per-run counts local and doing a proper two-pass max/tie handling) are the right fixes.

Concise checklist of improvements and gotchas to avoid:

  • Make the per-run counts a local array returned by the roll method so each simulation starts from zero.
  • Use zero-based loops: for (i = 0; i < counts.length; i++).
  • To handle ties either increment all tied faces (two-pass: find max, then increment every index equal to max) or pick one winner at random from the tied indices.
  • For debugging, limit iterations, print only the first few runs or print a summary every N runs, or write results to a file — avoid printing every iteration.
  • For reproducible experiments seed the RNG; for high-throughput simulation prefer ThreadLocalRandom in Java 7+.

Example pattern (illustrates a safe structure and a random tie-break):

static int[] simulateOneRun(int rollsPerRun) {
  int[] counts = new int[6];
  ThreadLocalRandom rnd = ThreadLocalRandom.current();
  for (int i = 0; i < rollsPerRun; i++) counts[rnd.nextInt(6)]++;
  return counts;
}

// in a batch loop: find max, collect tied indices, choose one at random, update wins[]

Final notes: occasional short-term clustering is normal for a fair RNG; apparent "bursts" in console output are often caused by very frequent printing and console buffering rather than the RNG itself. For statistical validation run large numbers of trials and use a chi-square test or plot the distributions to check uniformity.

Recommended Answers

All 14 Replies

31: rolls[diceValue - 1] = rolls[diceValue - 1] += 1;

That is positively wierd. Two assignments for the same variable like that - I'd have to read the JLS to know which was executed first!

What's wrong with

rolls[diceValue - 1]++;

Ditto line 58, except that I don't know why you are doing that increment anyway

Wow, I've never felt so dumb in my life xD That's definitely a mistake!
Still a few issues after correcting that, this is some output after about 15 seconds.

...
[258640, 9192, 1, 152006, 119871, 0]
[258640, 9192, 1, 152007, 119871, 0]
[258640, 9192, 1, 152008, 119871, 0]
[258640, 9192, 1, 152009, 119871, 0]
[258640, 9192, 1, 152010, 119871, 0]
[258640, 9192, 1, 152011, 119871, 0]
[258640, 9192, 1, 152012, 119871, 0]
[258640, 9192, 1, 152013, 119871, 0]
[258640, 9192, 1, 152014, 119871, 0]
[258640, 9192, 1, 152015, 119871, 0]
[258640, 9192, 1, 152016, 119871, 0]
[258640, 9192, 1, 152017, 119871, 0]
[258640, 9192, 1, 152018, 119871, 0]
[258640, 9192, 1, 152019, 119871, 0]
[258640, 9192, 1, 152020, 119871, 0]

Notice how the numbers generally stay the same, especially the last one, which NEVER increments?
Basically, I am just running some stats to see how random Java's "Random" Class really is, but it's mostly just personal expiramentation. I am just coding it because I can really, I wanna see if I get a number that generates more then others.

A couple of problems:

you don't re-initialise rolls on each call of roll(). It really should be a local variable in the method.

for(int i = 1; i < 6; i++) //Get highest index
just checks 5 values of i, not 6

(this is a bit subtle... ) You forgot about the case where two values have the same counts (which will be pretty common over 100 rolls). You find the first (lowest) value that has the highest count. If two values have the same count, then second one is never seen as "highest".

Sounds good, will try fixing in a few hours when I hop back on my PC.

Good catch with the two values being the same! In this case, you you add one to both? Or ignore it and not add anything? Either way, would you have to actually store each value, then check after getting them all? Or could it be done on the fly, like how I'm doing it?

In this case, you you add one to both? Or ignore it and not add anything?

That's up the programs eventual user! Personally I think adding 1 to both makes more sense

Either way, would you have to actually store each value, then check after getting them all?

Yes. One pass thru the array to find the highest count, then a second pass to increment all the values that have that count.

if 2 values have the same count, report both...

Actually, taking it a step further, what if more then two values have the same highest?

I wrote this code, which seems to work, but I dont know if its the Random or something actually wrong. Here's some more output, everything increments, however it does it in about 3 seconds 'bursts'. Like it increments one for about 3 seconds, then moves to another for about 3 seconds and keeps switching.

Heres what I have changed.

private static void rollConsec()
    {
        int[] tempRolls;
        while(true) //Keep repeating
        {
            tempRolls = new int[6];
            tempRolls = roll();
            int highestValue = 0;

            for(int check : tempRolls)
            {
                if(check > highestValue)
                    highestValue = check;
            }

            for(int i = 0; i < tempRolls.length; i++)
            {
                if(tempRolls[i] == highestValue)
                    highestRolls[i]++;
            }

            System.out.println(Arrays.toString(highestRolls)); //Print the array
        }
    }

Forgot the Output:

[34185, 91, 64, 10244, 527, 35703]
[34185, 91, 64, 10245, 527, 35703]
[34185, 91, 64, 10246, 527, 35703]
[34185, 91, 64, 10247, 527, 35703]
[34185, 91, 64, 10248, 527, 35703]

Can't see anything wrong there. Try printing the tempRolls array as well as the highestRolls, and look at the FIRST few lines of output. YOu should be able to see there where it's going wrong with just a few data points

Eclipse only stores a specific number of lines, and by the time I start and stop it, it's already went through a ton of lines.
I'll see if I can get it to slow down somehow, and I'll check the tempRolls array then too.

In rollConsec() you can change thewhile (true) to a do loop with a limited (eg 20) number of iterations

commented: First time I had to use a do loop :) +3

Found out what its doing. It isn't actually clearing the tempRolls, its adding them together.

tempRolls: [13, 18, 12, 18, 21, 18]
highestRolls: [0, 0, 0, 0, 1, 0]
tempRolls: [39, 26, 31, 33, 33, 38]
highestRolls: [1, 0, 0, 0, 1, 0]
tempRolls: [60, 50, 43, 50, 41, 56]
highestRolls: [2, 0, 0, 0, 1, 0]
tempRolls: [78, 68, 56, 68, 58, 72]
highestRolls: [3, 0, 0, 0, 1, 0]
tempRolls: [101, 83, 68, 88, 77, 83]
highestRolls: [4, 0, 0, 0, 1, 0]
tempRolls: [119, 100, 85, 97, 97, 102]
highestRolls: [5, 0, 0, 0, 1, 0]
tempRolls: [140, 117, 96, 110, 119, 118]
highestRolls: [6, 0, 0, 0, 1, 0]
tempRolls: [158, 131, 111, 123, 141, 136]
highestRolls: [7, 0, 0, 0, 1, 0]
tempRolls: [176, 152, 125, 139, 157, 151]
highestRolls: [8, 0, 0, 0, 1, 0]
tempRolls: [193, 166, 144, 155, 176, 166]
highestRolls: [9, 0, 0, 0, 1, 0]
tempRolls: [211, 180, 162, 171, 190, 186]
highestRolls: [10, 0, 0, 0, 1, 0]
tempRolls: [226, 199, 183, 186, 202, 204]
highestRolls: [11, 0, 0, 0, 1, 0]
tempRolls: [250, 213, 193, 201, 222, 221]
highestRolls: [12, 0, 0, 0, 1, 0]
tempRolls: [264, 227, 215, 220, 239, 235]
highestRolls: [13, 0, 0, 0, 1, 0]
tempRolls: [282, 247, 231, 233, 254, 253]
highestRolls: [14, 0, 0, 0, 1, 0]
tempRolls: [304, 266, 245, 247, 265, 273]
highestRolls: [15, 0, 0, 0, 1, 0]
tempRolls: [321, 288, 260, 260, 280, 291]
highestRolls: [16, 0, 0, 0, 1, 0]
tempRolls: [342, 298, 278, 278, 298, 306]
highestRolls: [17, 0, 0, 0, 1, 0]
tempRolls: [359, 313, 296, 301, 309, 322]
highestRolls: [18, 0, 0, 0, 1, 0]
tempRolls: [373, 332, 307, 323, 328, 337]
highestRolls: [19, 0, 0, 0, 1, 0]
tempRolls: [394, 345, 321, 337, 343, 360]
highestRolls: [20, 0, 0, 0, 1, 0]

No idea on how to fix it, I thought initializing tempRolls again would clear it? Wouldn't it?

Looks like a problem in the roll() method - did you change that to use a local array?

That fixed it! Thanks!

Some output now that it's fixed:

[99788, 99441, 99390, 99537, 99643, 99914]
[99788, 99442, 99390, 99537, 99643, 99914]
[99788, 99442, 99390, 99537, 99643, 99915]
[99789, 99442, 99390, 99537, 99643, 99915]
[99789, 99442, 99390, 99538, 99643, 99915]
[99790, 99442, 99390, 99538, 99643, 99915]
[99790, 99442, 99390, 99539, 99643, 99915]
[99790, 99442, 99391, 99539, 99643, 99915]
[99790, 99442, 99391, 99539, 99644, 99915]
[99791, 99442, 99391, 99539, 99644, 99915]
[99791, 99442, 99391, 99540, 99644, 99915]
[99791, 99442, 99391, 99540, 99644, 99916]
[99792, 99442, 99391, 99540, 99644, 99916]
[99793, 99442, 99391, 99540, 99644, 99916]
[99793, 99443, 99391, 99540, 99644, 99916]
[99794, 99443, 99391, 99540, 99644, 99916]
[99794, 99443, 99391, 99540, 99645, 99916]

Seems pretty random to me xD

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.