日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

我以前用过的一个洗牌算法

發(fā)布時(shí)間:2025/3/21 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我以前用过的一个洗牌算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
前兩天和幾個(gè)做在線棋牌游戲的朋友聚會(huì),聊到了洗牌算法,正好以前寫(xiě)過(guò)一些撲克牌的游戲,中間做了一個(gè)洗牌算法,就寫(xiě)了個(gè)例子給他們做試驗(yàn)。 基本思路很簡(jiǎn)單,就是交換法,54張牌排好,隨機(jī)選擇兩張牌交換,一般說(shuō)來(lái),只要交換次數(shù)足夠多,比如54張牌就交換54次,牌就已經(jīng)洗得很爛了,呵呵,可以打牌了。如果還不放心,那double,洗108次好了。 程序還是比較簡(jiǎn)單的,大家應(yīng)該一目了然,我花了差不多半個(gè)小時(shí)左右寫(xiě)出來(lái),又測(cè)試了一下。 Code:
  • #define?POKER_MAX?54????????????//54張撲克 ??
  • #define?POKER_COLOR_MAX?4???????//四種主花色 ??
  • #define?POKER_POINT_MAX?13??????//每種花色13張牌,J=11,Q=12,K=13 ??
  • ??
  • #define?POKER_COLOR_KING????4???//王的花色 ??
  • #define?POKER_COLOR_0???????0???//黑桃花色 ??
  • #define?POKER_COLOR_1???????1???//紅桃花色 ??
  • #define?POKER_COLOR_2???????2???//櫻花花色 ??
  • #define?POKER_COLOR_3???????3???//方塊花色 ??
  • ??
  • #define?POKER_KING_POINT_BIG????1???//大王的點(diǎn)數(shù) ??
  • #define?POKER_KING_POINT_LITTLE?0???//小王的點(diǎn)數(shù) ??
  • ??
  • ??
  • typedef?struct?_POKER_CARD_ ??
  • { ??
  • ????short?m_sID;????????//全序列排列時(shí)的ID(0~53) ??
  • ????char?m_cColor;??????//撲克花色 ??
  • ????char?m_cPoint;??????//撲克點(diǎn)數(shù) ??
  • }SCard; ??
  • const?unsigned?long?SCardSize=sizeof(SCard); ??
  • class?CPoker ??
  • { ??
  • public: ??
  • ????CPoker() ??
  • ????{ ??
  • ????????//先整齊排列54張牌,按黑紅櫻方順序,每種花色按0~12順序 ??
  • ????????int?i=0; ??
  • ????????int?j=0; ??
  • ????????int?nIndex=0; ??
  • ????????for(i=0;i<POKER_COLOR_MAX;i++) ??
  • ????????{ ??
  • ????????????for(j=0;j<POKER_POINT_MAX;j++) ??
  • ????????????{ ??
  • ????????????????SetPokerInfo(i,j,nIndex); ??
  • ????????????????nIndex++; ??
  • ????????????} ??
  • ????????} ??
  • ????????//王放在最后兩張 ??
  • ????????SetPokerInfo(POKER_COLOR_KING,POKER_KING_POINT_LITTLE,nIndex);??//小王 ??
  • ????????nIndex++; ??
  • ????????SetPokerInfo(POKER_COLOR_KING,POKER_KING_POINT_BIG,nIndex);?//大王 ??
  • ????} ??
  • ????~CPoker(){} ??
  • ????//一般說(shuō)來(lái),按牌總數(shù)決定洗牌次數(shù),已經(jīng)洗得很爛了 ??
  • ????void?Wash(int?nTime=POKER_MAX) ??
  • ????{ ??
  • ????????int?i=0; ??
  • ????????for(i=0;i<nTime;i++) ??
  • ????????????Random(); ??
  • ????} ??
  • ????//實(shí)際的游戲,從此處取洗好的牌張數(shù)據(jù) ??
  • ????bool?Get(unsigned?int?nIndex,SCard*?pCard) ??
  • ????{ ??
  • ????????if(POKER_MAX<=nIndex)?return?false; ??
  • ????????memcpy((char*)pCard,(char*)&m_Poker[nIndex],SCardSize); ??
  • ????????return?true; ??
  • ????} ??
  • ????void?PrintInfo(void) ??
  • ????{ ??
  • ????????int?i=0; ??
  • ????????SCard?Card; ??
  • ????????for(i=0;i<POKER_MAX;i++) ??
  • ????????{ ??
  • ????????????if(Get(i,&Card)) ??
  • ????????????{ ??
  • ????????????????printf("%02d?-?ID=%02d,?Color=%d,?Point=%02d\n", ??
  • ????????????????????i,Card.m_sID,Card.m_cColor,Card.m_cPoint); ??
  • ????????????} ??
  • ????????} ??
  • ????????printf("===============\n"); ??
  • ????} ??
  • private: ??
  • ????//給sID指定的牌張賦值 ??
  • ????void?SetPokerInfo(char?cColor,char?cPoint,short?sID) ??
  • ????{ ??
  • ????????m_Poker[sID].m_cColor=cColor; ??
  • ????????m_Poker[sID].m_cPoint=cPoint; ??
  • ????????m_Poker[sID].m_sID=sID; ??
  • ????} ??
  • ????//交換兩張牌 ??
  • ????void?Exchange(int?a,int?b) ??
  • ????{ ??
  • ????????char?szTemp[SCardSize]; ??
  • ????????memcpy(szTemp,(char*)&m_Poker[a],SCardSize); ??
  • ????????memcpy((char*)&m_Poker[a],(char*)&m_Poker[b],SCardSize); ??
  • ????????memcpy((char*)&m_Poker[b],szTemp,SCardSize); ??
  • ????} ??
  • ????//隨機(jī)選取兩張牌張交換洗牌 ??
  • ????//如果隨機(jī)數(shù)相等,發(fā)生碰撞,則b=a+1,總之不一樣就可以了。 ??
  • ????void?Random(void) ??
  • ????{ ??
  • ????????int?a=GetRandomBetween(0,POKER_MAX); ??
  • ????????int?b=GetRandomBetween(0,POKER_MAX); ??
  • ????????if(a==b) ??
  • ????????{ ??
  • ????????????b=a+1; ??
  • ????????????if(POKER_MAX<=b)?b=0; ??
  • ????????} ??
  • ????????Exchange(a,b); ??
  • ????} ??
  • private: ??
  • ????SCard?m_Poker[POKER_MAX]; ??
  • };??
  • 其實(shí)主要就是Wash這個(gè)函數(shù),默認(rèn)是洗54遍,當(dāng)然,調(diào)用者如果高興,多洗幾遍也沒(méi)問(wèn)題,呵呵。 用Get函數(shù)拿指定的撲克張子來(lái)用。 我試了一下,沒(méi)什么問(wèn)題,呵呵,刺激一下大家哈,從我測(cè)試代碼看,又是0bug。 不過(guò),這段代碼有個(gè)問(wèn)題,就是不是多線程安全的,起碼,一個(gè)線程洗牌,另外一個(gè)線程拿牌,會(huì)出錯(cuò)。所以,我根據(jù)《0bug-C/C++商用工程之道》里面的“資源鎖”概念,又封裝了一個(gè)加鎖的線程安全版。 Code:
  • class?CPokerWithLock ??
  • { ??
  • public: ??
  • ????CPokerWithLock(){} ??
  • ????~CPokerWithLock(){} ??
  • ????void?Wash(int?nTime=POKER_MAX) ??
  • ????{ ??
  • ????????m_Lock.Lock(); ??
  • ????????????m_Poker.Wash(nTime); ??
  • ????????m_Lock.Unlock(); ??
  • ????} ??
  • ????bool?Get(unsigned?int?nIndex,SCard*?pCard) ??
  • ????{ ??
  • ????????bool?bRet=false; ??
  • ????????m_Lock.Lock(); ??
  • ????????????bRet=m_Poker.Get(nIndex,pCard); ??
  • ????????m_Lock.Unlock(); ??
  • ????????return?bRet; ??
  • ????} ??
  • ????void?PrintInfo(void) ??
  • ????{ ??
  • ????????m_Lock.Lock(); ??
  • ????????????m_Poker.PrintInfo(); ??
  • ????????m_Lock.Unlock(); ??
  • ????} ??
  • private: ??
  • ????CPoker?m_Poker;?????//"資源鎖"概念,私有聚合,所有公有方法加鎖,確保安全性 ??
  • ????CMutexLock?m_Lock;??//這是《0bug-C/C++商用工程之道》里面的跨平臺(tái)安全鎖,見(jiàn)6.2小節(jié),P226頁(yè) ??
  • };??
  • 嗯,這個(gè)加鎖版本不是必須的,只有當(dāng)多線程環(huán)境時(shí)才需要。CMutexLock這個(gè)類我這里就懶得提供了,有書(shū)的朋友,自己去查書(shū)吧。 嗯,最后,給段測(cè)試代碼,大家可以看看效果。 Code:
  • inline?void?TestCPoker(void) ??
  • { ??
  • ????CPokerWithLock?Poker; ??
  • ????srand((unsigned?int)time(NULL)); ??
  • ????Poker.PrintInfo(); ??
  • ????Poker.Wash(); ??
  • ????Poker.PrintInfo(); ??
  • ????Poker.Wash(); ??
  • ????Poker.PrintInfo(); ??
  • }??
  • 上述代碼在VS2008下測(cè)試成功。有興趣的朋友,可以自己試試。嗯,如果沒(méi)有書(shū)的朋友,CPokerWithLock Poker;這句話可以改為CPoker Poker;,直接用非線程安全版本就好了。 大家看看,有什么問(wèn)題歡迎討論哈。 =======================================================
    在線底價(jià)購(gòu)買(mǎi)《0bug-C/C++商用工程之道》
    (直接點(diǎn)擊下面鏈接或拷貝到瀏覽器地址欄)
    http://s.click.taobao.com/t_3?&p=mm_13866629_0_0&n=23&l=http%3A%2F%2Fsearch8.taobao.com%2Fbrowse%2F0%2Fn-g%2Corvv64tborsvwmjvgawdkmbqgboq---g%2Cgaqge5lhebbs6qzlfmqmttgtyo42jm6m22xllqa-------------1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20---40--coefp-0-all-0.htm%3Fpid%3Dmm_13866629_0_0 肖舸

    總結(jié)

    以上是生活随笔為你收集整理的我以前用过的一个洗牌算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。