2014-03-27 88 views
0

我正在嘗試爲一副紙牌實現一個類。 「甲板」功能之一就是洗牌。執行洗牌的邏輯

void deck::shuffle() 
{ 
    int cardsleft = deck::cards; 
    for(int i = 0; i < cardsleft ; i++) 
    { 
     srand(time(NULL)); 
     int rdmn = rand() % cardsleft; 
     card tempcard = deck::dcards[rdmn]; 
     deck::dcards[rdmn] = deck::dcards[i]; 
     deck::dcards[i] = tempcard; 
    } 

}

僅僅是明確的,甲板::卡是一個整數計數沒有。在這套牌中留下的牌,牌組::卡德是這套牌中的牌陣列。

我的問題是:這並沒有給出很好的結果。難道我需要通過指針來傳遞參考嗎?如果是這樣,它是如何完成的?

或者,它可能只是壞算法?也許我只需要一個更好的洗牌邏輯。請說。注意:是的,我知道「algorithm.h」庫中有一個std :: shuffle std :: random_shuffle函數,但這些函數僅適用於向量,而不是數組,因爲我在這裏使用,不是?

UPDATE:NVM,我才意識到我的問題都可以在這裏回答: http://blog.codinghorror.com/the-danger-of-naivete/

所以這是一個邏輯的缺陷,不是我的實現。

+3

'std :: random_shuffle'和'std :: shuffle'使用任意隨機存取範圍。一個數組是一個隨機訪問範圍。 –

回答

2

如果你需要洗牌序列,你應該考慮std::random_shuffle(或在C++ 11中爲std::shuffle)。它按順序對元素進行重新排序,以便這些元素的每個可能的排列具有相同的出現概率。是的,它可以用於數組,而不僅僅是矢量。任何是「範圍」的東西。

現在回到你的代碼,你有種子的問題。生成(僞)隨機數的算法取初始值,即種子。給他們相同的種子他們產生相同的數字序列。這意味着你只需要產生一次隨機數(每個線程),否則你會一次又一次地產生相同的數字序列。在你的循環中,你會得到相同的數字,直到時間改變爲使用種子的新值。

+1

「只需要隨機數生成[或]一次(每個線程)」。根據cppreference.com,['srand()'](http://en.cppreference.com/w/cpp/numeric/random/srand)不保證是線程安全的,它的實現定義是否rand( )'本身就是。如果一個實現使用線程特定的數據,那麼你建議的可能是好的;如果它是鎖定的,那麼從多個線程中調用srand()會破壞週期性保證。無論如何 - 重點是需要諮詢實施文檔。 –

3

當你

srand(time(NULL)); 

你設置種子爲當前時間。由於此循環將在一秒鐘內完成(正常分辨率爲time函數),因此種子將在循環中重置爲相同的起始值,從而每次都會獲得相同的隨機數。

您應該將隨機數發生器只播種一次,優選儘早在main函數中播種。


您可能還想看看new PRNG functionality in C++11