1
public class Spell {

    // chance = (0, 100>
    private int chance;

    public void execute() {
        if (chance < 100) {
            /*
            chance:80
            random:40 ... if(true) ... succeed

            chance:80
            random:80 ... if (true) ... failed

            chance:80
            random:81 ... if (true) ... failed

            chance:79
            random:80 ... if (false) ... succeed

            chance:66
            random:<0,65> (66 numbers) ... if (false) ... succeed
            random:<66,99> (34 numbers) ... if (true) ... failed


             */
            if (chance <= (int) (Math.random() * 100)) {
                System.err.println("failed");
                return;
            }

        }
        System.out.println("succeed");

    }

    //Test
    public static void main(String[] args) {
        Spell spell = new Spell();
        spell.chance = 80;
        spell.execute();
    }
}

Is this correct way to calculate chance? I need certain things to happen chance% of times. I wonder whether I did some mistake here or whether it works.

Let's say we have chance = 80, I need it to succeed in 80% of times and fail in 20% of time. There are souts for that in code, where I will add a function later.

Pang
  • 9,564
  • 146
  • 81
  • 122
Nicke
  • 11
  • 3
  • You might want to use `Random::nextInt(int)` instead of `Math.random()`.. See http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint – azurefrog Apr 02 '17 at 22:01
  • You could also store your chance as a number between 0 and 1 (`0.8` for 80%) and don't multiply the result of `Math.random()` with 100. You check at the start would then be if the chance is less than 1. You could use a double for that. – Leon Apr 02 '17 at 22:03
  • I would need double for chance, is that better? I thought integer would be better as it is less of PC space. Does it work though? – Nicke Apr 02 '17 at 22:10
  • Have you tried it? It looks like it should work. To test this, though, you'd need to run `execute()` many times (maybe 1000) and see if the number of successes is close to what's expected (it is unlikely to be _exactly_ 80% of the number of trials, but it is highly likely to be somewhere close). – ajb Apr 02 '17 at 22:39
  • By the way, don't let PC space dictate whether to use a `double` or an `int`, unless you are planning on storing hundreds of millions of values in an array. PC's have far too much space to worry about this, especially for just one variable. – ajb Apr 02 '17 at 22:41
  • If `chance` is 99, `(int)(Math.random() * 100)` cannot give a value that will fail the test, so when chance is 99 you have a 100% chance of success. Conversely, if `chance` is 0 it's still possible to return a failure. – sh1 Apr 04 '17 at 04:13

1 Answers1

0

From the mathematical point of view your idea is correct. You fix a segment [0, 100) and get random number with equal distribution. The probability that generated number falls into segment [0,80) is 80%.

Taking into account suggestions in comments to your question, the code could look like this:

import java.util.Random;

public class Spell {
    private int chance;
    private Random rnd = new Random(System.currentTimeMillis());

    public Spell(int chance) {
        //TODO: Check that chance is inside [0, 100]
        this.chance = chance;
    }

    public void execute() {
        if (rnd.nextInt(100) <= chance)
            System.out.println("succeed");
        else
            System.err.println("failed");
    }
}

Finally, you will see "succeed" printed with chance probability.

ilya
  • 958
  • 2
  • 9
  • 16