Question

thanks in advance for taking time to look at my Q. and anyone with the same problem i hope we get a solution...

so basicly i have an app that spins 2 coins at the same time and displays what the result is.

This method generates the first coin...

    public void coinResult1(){
     ImageView coin1View = (ImageView) findViewById(R.id.coin1);
     Random r = new Random();
     int coin1result = r.nextInt(2);

     if (coin1result == 0){
        coin1View.setBackgroundResource(R.drawable.coinheads);
        coinresult1 = 0;
     }
        else if (coin1result == 1) {
            coin1View.setBackgroundResource(R.drawable.cointails);
            coinresult1 = 1;
        }
}

and this is for the second coin

public void coinResult2(){
    ImageView coin2View = (ImageView) findViewById(R.id.coin2);

    Random r = new Random();
    int coin2result = r.nextInt(2);

    if (coin2result == 0){
        coin2View.setBackgroundResource(R.drawable.coinheads);
        coinresult2 = 0;
    }
        else if (coin2result == 1) {
            coin2View.setBackgroundResource(R.drawable.cointails);
            coinresult2 = 1;
        }
}

this is linked to onclick() of button which check the results to a player selection

public void checkResult(){
        coinResult1();
        coinResult2();
        coinResult = coinresult1 + coinresult2;
        if (coinResult == playerSelection){
            playerWins();
            buttonsReset();
        }
        else {
            playerLost();
            buttonsReset();
        }
    }

Now the only problem i have is... the results of both coins of 1000 presses are this... HeadsHeads 54%

HeadsTails 2%

TailsTails 44%

of 1000000 spins was roughly the same percentages

when each coin result was counted seprately

COIN1 heads 53% tails 47%

COIN2 heads 48% tails 52%

Now my friend says their is something wrong with those odds....beacause HeadsTails wasnt a high enough percent, hes expecting it to be close to 33% each combination at random

the code seems to favour HeadsHeads and TailsTails or HeadsTails.....ive tried several times and keep getting a low % of HeadsTails

can anyone shead some light on whats going on....and what is causing HeadsTails to rarely come out?

hope to hear back soon

Était-ce utile?

La solution

Your repeated instantiation of Random is ruining the statistical properties of the generator.

You need to create one instance and pass that into your functions. Better still, use a field in your class.

Please refer to this question for concerns over thread safety of the Random class:Is Random class thread safe?. It seems to suggest that you should synchronize the nextInt calls.

Autres conseils

You should never re-create random number generator over and over again:

  public void coinResult1(){
    ImageView coin1View = (ImageView) findViewById(R.id.coin1);
    Random r = new Random(); // <- That's the source of errors!
    int coin1result = r.nextInt(2);
    ...

Instead, create random generator instance once and for all:

  // Simplest, not thread-safe amendment
  private static Random s_Gen = new Random();
  ...

  public void coinResult1(){
    ImageView coin1View = (ImageView) findViewById(R.id.coin1);

    int coin1result = s_Gen.nextInt(2);
    ...

The cause of the misbehaviour is that when you re-create Random it often re-initializes from the same seed (which is usually current time) and so generates the same values.

You must create only one instance of Random.

    private Random r;

    // initialize r in onCreate or somehere else only once 

protected void onCreate(Bundle savedInstanceState){
            // ...
    r = new Random();
}

public void coinResult1(){
     ImageView coin1View = (ImageView) findViewById(R.id.coin1);
     int coin1result = r.nextInt(2);

     if (coin1result == 0){
        coin1View.setBackgroundResource(R.drawable.coinheads);
        coinresult1 = 0;
     }
        else if (coin1result == 1) {
            coin1View.setBackgroundResource(R.drawable.cointails);
            coinresult1 = 1;
        }
}

public void coinResult2(){
    ImageView coin2View = (ImageView) findViewById(R.id.coin2);
    int coin2result = r.nextInt(2);

    if (coin2result == 0){
        coin2View.setBackgroundResource(R.drawable.coinheads);
        coinresult2 = 0;
    }
        else if (coin2result == 1) {
            coin2View.setBackgroundResource(R.drawable.cointails);
            coinresult2 = 1;
        }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top