Pregunta

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

¿Fue útil?

Solución

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.

Otros consejos

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;
        }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top