洗牌 發牌演算法 打亂撲克牌順序

2021-06-14 10:16:26 字數 4872 閱讀 7530

洗牌的演算法有很多,這裡主要介紹下幾種主要的演算法。

方法一:每次找乙個隨機的位置,然後將這54個數放到找的位置中。

步驟:1.用乙個整型陣列記錄各個位置是否已經放置了數,如果放置了則不為0,否則為0。所以在演算法開始的時候,初始化此陣列每個元素的值都為0.

2.每次產生乙個0-53之間的數,看這個位置是否放置了數,如果已經放置了,則繼續採用同樣的方法找乙個隨機的位置進行判斷,如果這個位置還未放置,則設定此位置。

3.反覆執行步驟2,直到所有的位置都放好了數。

**實現如下:

1

void shuffle(int *dest,intn)2

while (dest[pos]!=0

);10

11 dest[pos]=card;12}

13}1415

void

main()16;

18 shuffle(dest,54

);19

for (int i=0;i<54;i++)

2023 }

此方法有個缺點就是很耗時間,因為隨著空位置越來越少,尋找會越來越困難。

方法二:就是先對陣列進行初始化,然後隨機交換陣列中任意兩個元素。交換的次數越多就越隨機。此方法也很簡單,而且時間複雜度也比較低,計算量也不大。

**實現如下:

1

void shuffle ( int a, int

n )

213 }

方法三:它的基本思想是初始化乙個vector,順序加入所有牌,即1-54個數,然後從這個vector中隨機抽取乙個到另乙個vector中,將這個過程執行54次即可完成。

**的實現如下:

1

void vectorshuffle(vector &unshuffle,vector &shuffled)210

}111213

void

main()

1420

vectorshuffle(uncard,carded);

21for (int j=0;j<54;j++)

2225 }

ps:stl中也有乙個封裝好了的洗牌演算法-random_shuffle。使用方法:如果定義有 vectordatas,那麼直接呼叫該函式。例如:random_shuffle(datas.begin(),datas.end()); 還可以定義起始迭代器和末尾迭代器來對序列中的某一部分進行洗牌,並且所耗費的時間也較少。

[code=html]

本程式實現了一般撲克牌遊戲的洗牌、發牌和理牌過程,程式模擬了對四個玩家的發牌,且能讓各自玩家按大小順序整理自己的手牌。牌的大小順序按鬥地主的規則(但無大小王)。

本程式定義了乙個牌的結構體,其成員變數是兩個字元指標。乙個指向點數的字元陣列,另乙個指向花色的字元陣列。考慮到牌的整理需要比較兩張牌的大小,而字元不太好比較,從而構造了乙個輔助函式value來實現將字元轉換為整數。程式得最後還對桌牌和手牌進行了檢測,看是否有重複的牌。

演算法說明:

發牌演算法

void deal(card *deck,card (*player)[13]) }

}排序演算法

void  insertsort ( card *r) 

} // insertsort

測試演算法

測試桌牌和手牌是否有重複的牌。其思想是從第一張開始與後面的牌一次比較,直到找到一張與待比較的牌相同的或者倒數第二張與最後一張牌比較後終止。

演算法描述:

for(i = 0; i 

// 若沒有重複的牌不提示任何資訊

變數說明:

一.  張牌(card)都用乙個 strcut card 結構體型別來表示具體定義如下 struct card card;

再定義兩個字元陣列分別儲存牌的點數和花色:

char *face = ;

char *suit = ;

定義兩個card型陣列 deck[52],player[4][13],deck用與儲存桌牌,player用於儲存玩家手牌。

[/code]

[cpp]view plain

copy

print?

// 撲克牌發牌遊戲 -- 第一次上機作業

/* 整個程式由三部分組成

1.撲克牌初始化

2.洗牌

3.發牌

4.玩家各自將手牌排序(按黑紅紫坊從小到大的排序,2點最大)

*/#include 

#include 

#include 

#include 

typedef

struct card card;   

card deck[52], player[4][13];    

char *face = ;  

char *suit = ;  

// 比較時用的牌值

void initdeck (card * , char * , char *);  

void shuffle (card *);  

void deal (card * , card (*)[13]);  

void sort (card (*)[13]);  

int  value (char *);  

void disply(void );  

int locat(card *, int , card , int (*)(card, card));  

int equl(card, card);  

void testcard(card *, card (*)[13]);  

int main()  

void initdeck (card *pdeck, char *pface, char *psuit)  

}  void shuffle (card *pdeck)  

}  void deal (card *pdeck , card (*pplayer)[13])   

}  }  

void sort (card (*pplayer)[13])  

for (q = j-1; q > p; q--)  

pplayer[i][q+1] = temp;  

}  }  

}  int value(char *str)  

return i;  

}  void disply()  

}  }  

void testcard(card *pdeck, card (*pplayer)[13])  

}  // 測試桌牌是否重複

for (i = 0; i 

}  // 測試手牌是否重複

}  }  

int locat(card *pdecks, int len, card deck, int (*compare)(card , card ))  

int equl(card card1, card card2)  

洗牌演算法(打亂撲克牌順序)

問題描述 有乙個大小為 n 的有序陣列,如何打亂元素順序,使得任一元素在陣列的任一位置出現的概率都為 1 n?也就是說對於大小為 n 的有序陣列,有 n!種排列方式,要求能等概率的得到這 n!種結果。思路一 每次從原始陣列中隨機取乙個之前未取過的元素,新增到新陣列中。選取方法是 生成乙個 1 rem...

模擬撲克牌的洗牌發牌

在記憶體中模擬出一副牌,然後模擬洗牌,發牌等動作 流程 構建一副牌儲存到乙個陣列中 洗牌 建立玩家 向玩家發牌 輸出每個玩家的牌 include include include include include 一副牌的數量 define card count 54 定義撲克的花色,黑,紅,梅,方,小...

撲克牌洗牌演算法 random shuffle

撲克牌洗牌有多種演算法 第1個 每次從原陣列a取出範圍 1,i 的數放入b陣列。缺點是每次都要將陣列i後面的元素進行移動。是乙個o n2 演算法 void xipai int n n for int i 1 i x i 第2種 每次取範圍 1,i 1 的數,然後與最後乙個元素做交換。這樣的複雜度優化...