0

I am building a game, I want to pick a random number between 0 to n, I want to make that picking a higher number will have lower chances.

So I asked this question, and based on amit answer, I wrote this:

public class Test {
    private static Random random = new Random();

    public static void main(String[] ars) {
        int n = 30;
        float x = 5f;

        int[] results = new int[n];
        for (float i = 1; i <= 10000; i++) {
            int choose = pickANumber(n, x);
            results[choose]++;
        }
        for (int i = 0; i < results.length; i++) {
            System.out.println(i + "\t" + results[i]);
        }
    }

    static int pickANumber(int n, float x) {
        ArrayList<Float> values = new ArrayList<>();
        n += 2;
        for (float i = 2; i < n; i++) {
            float value = i * (i - 1) / (2f * x);
            values.add(value);
        }
        float max = ((n - 1) * (n - 2) / (2 * x));
        return pickANumber(max, values);
    }

    static int pickANumber(float max, ArrayList<Float> values) {
        float number = random.nextFloat() * max;
        int i = Collections.binarySearch(values, number);
        if (i < 0) {
            i = i * -1 - 1;
        }
        return i;
    }
}

Output of how many time I picked each number with 10,000 runs.

0   22
1   47
2   59
3   95
4   109
5   142
6   127
7   175
8   188
9   224
10  243
11  249
12  270
13  268
14  340
15  356
16  362
17  345
18  444
19  430
20  469
21  479
22  495
23  493
24  522
25  583
26  587
27  597
28  648
29  632

The problem is that it does not matter what value of x I choose, I always get the same output.

I need to find a way to fix this algorithm so x will affect the ratio of chances between picking up two different values, while the main idea will remain: Picking up higher values will be harder.

Community
  • 1
  • 1
Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
  • 2
    I copy your code to my Eclipse project (without changes) and it gives me a different output each time I execute it. Are you sure your code it's wrong? – Francisco Romero Jun 07 '15 at 23:39

1 Answers1

1

Would this be ok? If you use the additive version, you'll end up having the same probabilities always. I'm using the updated multiplicative version.

Also, use x<1 for lower chance of getting higher values. And x>1 otherwise.

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

public class Main {
    private static Random random = new Random();

    public static void main(String[] ars) {
        int n = 30;
        double x = 0.9;

        double[] aux = makeAux(n, x);
        int[] results = new int[n];
        for (float i = 1; i <= 10000; i++) {
            results[pickANumber(aux)]++;
        }
        for (int i = 0; i < results.length; i++) {
            System.out.println(i + "\t" + results[i]);
        }
    }

    static double[] makeAux(int n, double x) {
        double[] aux = new double[n];
        aux[0] = x;
        for (int i = 1; i < n; i++)
            aux[i] = aux[i - 1] + Math.pow(x, (i + 1));
        return aux;
    }

    static int pickANumber(double[] aux) {
        double number = random.nextDouble() * aux[aux.length - 1];
        int i = Arrays.binarySearch(aux, number);
        if (i < 0)
            i = -i - 1;
        return i;
    }
}
Juan Lopes
  • 10,143
  • 2
  • 25
  • 44