2014-03-06 29 views
2

感謝您抽出時間來看看我問及同樣的問題我希望我們能解決任何...2隨機量似乎給了幾乎相同的結果提前

所以basicly我有一個旋轉的應用2個硬幣同時顯示結果。

此方法生成的第一硬幣...

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; 
     } 
} 

,這是第二個硬幣

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按鈕()的檢查結果給玩家選擇

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

現在我唯一的問題是... 這兩個結果都是c的1000臺印刷機oins此... HeadsHeads 54%

HeadsT​​ails 2%

TailsTails 44%

的百萬自旋

是大致相同的百分比

當各硬幣結果seprately計數

COIN1頭53%尾部47%

COIN2頭48%尾部52%

現在,我的朋友說,他們的一些錯誤的機率....東陽HeadsT​​ails wasnt足夠高的百分比,HES期待它接近33%,每個組合隨機

代碼似乎有利於HeadsHeads和TailsTails或HeadsT​​ails ..... ive嘗試了幾次,並繼續得到HeadsT​​ails的低%

任何人都可以指出什麼正在發生....什麼是導致HeadsT​​ails很少出來?

希望聽到很快回來

+2

默認情況下,「Random」的實例會播放系統時間。如果兩個實例碰巧在毫秒內創建,它們將有效地生成相同的僞隨機數。 –

回答

5

你重複的Random實例是破壞發電機的統計特性。

您需要創建一個實例並將其傳遞到您的函數中。更好的是,在你的班級中使用一個領域。

請參閱此問題,以關注Random類的線程安全問題:Is Random class thread safe?。它似乎暗示你應該呼叫synchronizenextInt

+0

對不起,您提到過哪些線程問題?根據http://stackoverflow.com/questions/5819638/is-random-class-thread-safe隨機類是線程安全的... –

+0

@ GermannArlington:這是非常好的。我是一個老偏執的貓。你介意我是否將這一點吸收到我的答案中? – Bathsheba

+0

當然,請做 –

1

你應該從未一遍遍重新創建隨機數生成器:除了

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); 
    ... 

,創建隨機生成器實例一勞永逸

// 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); 
    ... 

的原因錯誤行爲是當你重新創建Random時,它經常會重新初始化相同的種子(通常是當前時間)和因此產生相同的值的

+0

謝謝德米特里,我清楚地理解了 – user3387276

0

您只能創建一個隨機實例。

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; 
     } 
}