0

I am making a game and I need to use a random number generator. I need it to take something from an array and need stuff in the array to have a different probability of getting picked from the array. here's my code (note: the chance of the number getting picked goes down with each number)

int randomInt(int lower, int upper) 
{ 
    int num;
    int s; 
    for (s = 0; s < 1; s++)
    { 
        num = (rand() % 
           (upper - lower + 1)) + lower; 
    }
    return num; 
} 


const char *yes[5] {"one", "two", "three", "four", "five"};
Nerdboi
  • 1
  • 2
  • `yes[randomInt(0, sizeof(yes) / sizeof(*yes))]`? (no because this doesn't satisfy the note) – MikeCAT Feb 19 '21 at 22:57
  • 1
    "the chance of the number getting picked goes down with each number" does not uniquely specify a probability distribution on the numbers. Your question is vague. – John Coleman Feb 19 '21 at 22:58
  • @JohnColeman sorry, I am meaning like the chance of picking 1 would be 34%, 2 would be 23%, and continue going down. but those chances are just random percentages – Nerdboi Feb 19 '21 at 23:08
  • @Nerdboi Why 34% and 23%? Those numbers don't follow from your description. There are infinitely many ways to pick 5 decreasing numbers in the range `[0,1]` which sum to 1. – John Coleman Feb 19 '21 at 23:11
  • @JohnColeman I was just using those percentages as examples, in the final project they wouldn't be like that. – Nerdboi Feb 19 '21 at 23:15
  • I wasn't sure if you were asking how to find the probabilities or how to select with the given probabilities. Given the probabilities, it is straightforward to pick an item according to them. See for example [this question](https://stackoverflow.com/q/1761626/4996248). (That question is tagged C++ but the accepted answer sticks mostly to the part of C++ which overlaps C). You could also use [this answer](https://gamedev.stackexchange.com/a/162977) from a question on the game dev site. – John Coleman Feb 19 '21 at 23:24

1 Answers1

1

In order to make this happen, you should also make an array to define for each element what the probability is that it gets picked. For instance, you could use the array {0.25, 0.4, 0.1, 0.05, 0.2}. Make sure that the total probability is 1. Now, we generate a random float between 0 and 1. If the number falls between [0, 0.25], then we pick the first element. If the element falls between [0.25, 0.65], we pick the second element. Every time the interval is exactly the size of the element in the probabilities array that you define. This way we ensure that each element has exactly the probability of being picked that you define in your array.

The following function random_element_index accomplishes exactly that:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define LENGTH 5

int random_element_index(float* probs) {
    // This line generates a random float between 0 and 1
    float random = (float)rand() / (float)RAND_MAX;
    float sum = 0;

    for (int i = 0; i < LENGTH; i++) {
        sum += probs[i];
        if (random < sum)
            return i;
    }

    return -1;
}

int main() {
    srand(time(NULL));
    const char *yes[LENGTH] = {"one", "two", "three", "four", "five"};

    float probabilities[LENGTH] = {0.25, 0.4, 0.1, 0.05, 0.2};
    int index = random_element_index(probabilities);

    printf("%s\n", yes[index]);

    return 0;
}

If you're not convinced, here is a function you could use to see it in action:

void test_random() {
    float probabilities[LENGTH] = {0.25, 0.4, 0.1, 0.05, 0.2};
    int test[LENGTH] = {0, 0, 0, 0, 0};

    for (int i = 0; i < 10000; i++)
        test[random_element_index(probabilities)]++;

    for (int i = 0; i < LENGTH; i++)
        printf("%d\n", test[i]);
}
Chrysophylaxs
  • 5,818
  • 3
  • 10
  • 21