2012-12-24 42 views
1

我試圖運行一百萬卡片遊戲模擬返回一個百分比「賭場房子的邊緣。」這將輸出一個隨機洗牌一百萬次?蘭德()C++

我對rand()函數的理解還不夠清楚,無法確定這是否會每次都會產生一個新的混洗或者它是否有限制。換句話說,在一百萬場比賽中,相同模式的洗牌會出現嗎?

srand(time(NULL)); 

for (int games=0;games<iGames;games++){ 

        ///shuffle/// 
for (int i=0; i<(iUserDeckSize-1); i++) { 
    int r = i + (rand() % (iUserDeckSize-i)); // Random remaining position. 
    card temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; 
} 

// rest of card game code goes here 
} 
+1

如果我的記憶是正確的,那麼''應該有一個洗牌......這裏:http://www.cplusplus.com/reference/algorithm/random_shuffle/ – nhahtdh

+0

rand()是一個僞隨機數發電機。這意味着*最終*(並且最終可能是一個非常大的 - 不關心)將會有重複序列。然而,由於這種重新啓動可能發生「並不總是在洗牌開始時」,因此似乎可能有比所使用的PRNG的週期長度更多的* shuffle排列。 – 2012-12-24 05:51:21

+1

我相信它是特定於實現的,請參閱http://stackoverflow.com/questions/1026327/what-c​​ommon-algorithms-are-used-for-cs-rand。但是如果實際的應用開始重複這麼快,我會感到震驚的,我想至少你會進入int32所允許的數十億美元。 – PeterJ

回答

0

不是因爲兩個原因(一個你想過的,一個不那麼明顯)。

您正在使用的算法是錯誤的。撇開令人擔憂的-1(最後一個元素將不會被洗牌),你有n^n可能的運行(接收隨機數的空間),而有n!可能洗牌。一般而言,n!不是n^n的因子,因此您有偏見的產出(即某些結果會比其他結果更頻繁地發生)。我會建議執行Knuth-Tares shuffle或使用<algorithm>之類的已實施的算法,如random_shuffle

這就是說 - 你需要有至少有n!狀態的PRNG。根據deck的大小rand()可能不夠 - 它通常有〜48位,而標準的52張牌有〜225位的狀態(log2(52!)) - 換句話說,沒有機會觸及某些序列(它可能不會是一個問題,但更好的PRNG的開銷可以忽略不計)。我會看boost random,因爲它有幾個很好的PRNG實現,並且至少有一個可能足夠好(例如mt11213b爲52卡示例)。