PerlinNoise2d
George Rowland

George Rowland

The Probability Of Randomness

In my previous post, I talked about the dropping of materials from asteroids. I was using Unity’s Random.value to determine the type to drop and needed to add probability per material value. As with any computer programming problem, there are many solutions. An example of my solution is below. I will walk you through this algorithm here and explain how I use it in material choosing.
First, we create an array with our probabilities in it. My goal when creating these is to make them equal 100 or a multiple thereof. Keeping these multiples of 100 makes it easy for me to calculate the percentage I am attempting to portray. In the example code below I do this 10,000 times to show the probability function returns the proper amount of each item given a large sample size. In the game, I have a dictionary with the type as the key and the count of the item as the value. I do this six times to determine the types to return, then add a random value from 1 to 100 to the value of that key. In this fashion, you could get six of the highest value items, only one that would become an object representing the full value of all six. You may remember from a few weeks ago that having fewer actual material objects floating in the scene reduces the overall load on the physics engine.

 

Random.Next(0, 100) with probabilities at 40, 25, 15, 10, 8, 2


    private static void ProbabilityFunction()
    {
        //To store the count of each item
        int[] randomNumbers = new int[6];
        //The percentage of each item array
        int[] percentages = new int[]{40, 25, 15, 10, 8, 2};
        //Used to determine how close we were to the projected percentage
        int[] difference = new int[6];
        //Get the sum of percentages used, I try to use 100 to make it easy on my brain
        int maxNumber = percentages.Sum();
        //Holder for the current random number
        int currentNumber;

        //Do this 10000 times to show the probability is working
        for(int i = 0; i < 10000; i ++)
        {
            //Get a number between 0 and the sum of probabilities
            currentNumber = rand.Next(0, maxNumber);
            
            //Look at each percentage and determine if the number falls into that bucket.  If not subtract that bucket from the current number and check the next number.
            for(int x = 0; x < percentages.Length; x ++)
            {  
                if(currentNumber < percentages[x])
                {
                    randomNumbers[x] ++;
                    break;
                }
                else
                {
                    currentNumber -= percentages[x];
                }
            }
        }

        for(int i = 0; i < randomNumbers.Length; i ++)
        {
            difference[i] = Math.Abs(percentages[i] - randomNumbers[i]);
        }

        Console.Write("Probability : 0: {0} 1: {1} 2: {2} 3: {3} 4: {4} 5: {5}", randomNumbers[0], randomNumbers[1], randomNumbers[2], randomNumbers[3], randomNumbers[4], randomNumbers[5]);
        Console.WriteLine(" Diff : {0}", difference.Sum());
    }

Percentage 0: 4000 1: 2500 2: 1500 3: 1000 4: 800 5: 200
Probability : 0: 3929 1: 2514 2: 1551 3: 980 4: 841 5: 185 Diff : 210
Probability : 0: 3980 1: 2525 2: 1461 3: 1023 4: 827 5: 184 Diff : 148
Probability : 0: 4008 1: 2517 2: 1477 3: 1028 4: 765 5: 205 Diff : 115
Probability : 0: 3936 1: 2477 2: 1573 3: 957 4: 833 5: 224 Diff : 258

Share this post