关于java:2个randoms似乎给出了几乎相同的结果

2 randoms seem to give near identical result

提前感谢你花时间看我的问题。如果有任何人有同样的问题,我希望我们能找到解决办法…

所以基本上我有一个同时旋转2个硬币并显示结果的应用程序。

这种方法产生第一枚硬币…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    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;
        }
}

这是第二枚硬币

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
        }
}

这链接到按钮的onclick(),该按钮将结果检查到玩家选择。

1
2
3
4
5
6
7
8
9
10
11
12
13
public void checkResult(){
        coinResult1();
        coinResult2();
        coinResult = coinresult1 + coinresult2;
        if (coinResult == playerSelection){
            playerWins();
            buttonsReset();
        }
        else {
            playerLost();
            buttonsReset();
        }
    }

现在我唯一的问题是…这两个硬币的1000次印刷的结果是…头部54%

头巾2%

尾楼梯44%

在1000000次旋转中,大约相同的百分比

当每枚硬币的结果被分开计算时

Coin1头53%尾47%

Coin2头48%尾52%

现在我的朋友说他们的赔率有问题……因为头巾的比例不够高,他希望每个组合的赔率都接近33%。

代码似乎倾向于头尾楼梯或头尾……我试了几次,头尾的比例一直很低。

有人能解释一下到底发生了什么……是什么导致了头巾很少出现?

希望很快能听到回音


您反复实例化Random会破坏生成器的统计属性。

您需要创建一个实例并将其传递到您的函数中。更好的是,在课堂上使用一个字段。

有关Random类的线程安全问题,请参阅此问题:随机类线程安全吗?.似乎建议您应该拨打synchronizenextInt电话。


您不应该反复地重新创建随机数生成器:

1
2
3
4
5
  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);
    ...

相反,一次性创建随机生成器实例:

1
2
3
4
5
6
7
8
9
  // 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);
    ...

错误行为的原因是,当您重新创建随机的时候,它经常从相同的种子(通常是当前时间)重新初始化,从而生成相同的值。


只能创建一个随机实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    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;
        }
}