2012-06-28 39 views
2

我遇到了我製作的小遊戲存在的問題。Rand生成相同的數字

#include "stdafx.h" 
#include <iostream> 
#include <cstdlib> 
#include <ctime> 
using namespace std; 

int main() 
{ 
int span = 100; 
srand(time(0)); 
int TheNumber = static_cast<double> (rand()) /RAND_MAX * (span -1) +1; 
cout << "You need to guess the number between 1 and " << span << endl; 
int mynumber; 
int numberofAttempts = 0; 

do { 
    cout << ++numberofAttempts <<" Attempt: "; 
    cin >> mynumber; 
    if (mynumber > TheNumber) 
     cout <<"Lower!" << endl; 
    else if (mynumber < TheNumber) 
     cout <<"Higher!" << endl; 
} while (mynumber != TheNumber); 

cout << "SUCESS!!!" << endl; 
return 0; 
} 

遊戲應該產生0-100之間的隨機數,你應該猜到了。運行這個代碼15-20次後,相同的數字甚至產生了8次(在我的例子中是2)。

我知道沒有絕對的隨機數,它使用一些數學公式或其他東西來得到一個。我知道使用srand(time(0))使它依賴於當前時間。但是,我怎樣才能使它更「隨意」,因爲我不想讓我發現上面提到的東西。

第一次運行它的結果是11,再次運行後(猜測正確的數字後),它仍然是11,即使時間改變了。

+0

我剛剛更新了最後一部分,猜測後(有些秒必須通過),數量仍然相同。 – Marink

+0

將TheNumber的聲明更改爲'int TheNumber = rand()%100 + 1;' – jrok

+1

@jrok,不好的建議。 rand()的低位比特是非常隨機的。 –

回答

3

[ADDITION1]

,如果你真正希望尋找到更好的隨機數生成,那麼這是一個很好的算法,開始使用:

http://en.wikipedia.org/wiki/Mersenne_twister

但請記住,任何「計算機生成「(即數學生成的)隨機數僅爲僞隨機數。僞隨機意味着雖然算法的輸出看起來具有正態分佈,但如果知道輸入種子,它們確實是確定性的。真隨機數是完全不確定的。

[原文] 嘗試只是以下行之一:

rand() % (span + 1); // This will give 0 - 100 
rand() % span;  // this will give 0 - 99 
rand() % span + 1; // This will give 1 - 100 

相反的:

(rand()) /RAND_MAX * (span -1) +1 

另外,不要投的,其結果爲double,然後放入一個int。

看看這裏也:

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

響應評論! 如果你使用:

rand()/(span + 1); 

那麼爲了0和100之間,以獲取值,然後從蘭特的輸出值的確會必須是0和(100 * 100)之間,並且這種性質必須是保證。這是因爲分工簡單。當rand()產生一個101 - 201時,1的值基本上會彈出,當rand()輸出值爲202 - 302等時,2會跳出分割區域。

在這種情況下,您可能能夠在100 * 100處獲得僅爲10000的值,並且在32位空間中肯定存在大於此值的整數,但通常情況下,除法不允許您利用提供的全部號碼空間!

+0

您的意思是rand()/(span + 1); ,因爲我不能使用%,因爲左操作數有兩倍。那麼這導致了同樣的事情。在更多的嘗試中產生相同的數字(在我必須重新運行程序之間有一段時間之後)。 – Marink

+0

不,我的意思是我放了,看這裏! http://www.cplusplus.com/reference/clibrary/cstdlib/rand/ – trumpetlicks

+0

對不起,我在這一個壞,我忘了刪除static_cast 。這有竅門,謝謝。 – Marink

1

首先,rand()/RAND_MAX不給出0和1之間的數字,它返回0.這是因爲RAND_MAX在rand()的結果中適合0次。兩者都是整數,所以用整數除法它不返回浮點數。

其次,RAND_MAX的大小可能與INT相同。然後將RAND_MAX乘以任何東西都會導致溢出。

+1

他正在將'rand()'轉換爲double。 –

+0

在這種情況下,rand()給出一個介於0和RAND_MAX之間的隨機數,使其在1和span間的間距(int span = 100)之間生成一個數字,我用RAND_MAX分割它(然後跨度將介於0和1)。 – Marink

2

rand()有許多問題。你遇到了其中的一個,那就是前幾個值不是「隨機的」。如果您必須使用rand(),放棄前四項或rand()的結果總是一個好主意。

srand (time(0)); 
rand(); 
rand(); 
rand(); 
rand(); 

rand()另一個問題是,將低階位是出了名的非隨機的,甚至在上述劈後。在某些系統中,最低位的位交替爲0,1,0,1,0,1,...使用高位位總是更好,例如通過使用商而不是餘數。

其他問題:非隨機性(大多數實現rand()未通過大量隨機性測試)和短週期。由於所有這些問題,最好的建議是使用除rand()之外的任何東西。

相關問題