鬥地主遊戲的基本算法實現
by -wojiushi3344
QQ:513670524
棋牌遊戲交流羣:246671414
掃描二維碼,添加好友,獲取更多的鬥地主編程技術
轉載請說明出處
PS:首先祝朋友們5,1節快樂!!閒來無事,今天來寫一下鬥地主遊戲的基本實現,寫得不好,大家別噴哈!!具體實現還得參見源代碼。朋友們如果你有更好的建議可以到我博客留言討論。謝謝!
博客地址:http://blog.csdn.net/wojiushi3344
發牌動畫:
原理:沒隔一段時間更新定時器,然後再更新圖片到不同的位置實現地主發牌的動畫。
具體實現:運用初中數學知識,2點確定一條直線(y=kx+b).
根據上圖可以看出,P點和A,B,C三點連接成3條不同的直線。我們要實現發牌動畫,首先需要要發出的牌從P點依次移動到A,B,C三點。然後再按着途中箭頭的方向來更新點的座標,這樣依次執行下去,直到要發的牌剩3張時發牌動畫截止。
定義3個vector,來存入我們已經發了的牌的座標。
vector<card_coor> player_a;
vector<card_coor> player_b;
vector<card_coor> player_c;
具體的代碼實現:
- void CGame::calculateTwoPoint(float x1,float y1,float x2,float y2)//計算兩點間的線段
- {
- m_k=(y1-y2)/(x1-x2);
- m_b=y1-x1*m_k;
- }
void CGame::calculateTwoPoint(float x1,float y1,float x2,float y2)//計算兩點間的線段
{
m_k=(y1-y2)/(x1-x2);
m_b=y1-x1*m_k;
}
根據2點的座標,來計算出K和b的值。
繪製使將X座標用Y座標來表示,這樣的好處是,當我們更新Y座標時X座標也隨之更新,從而達到我們想要實現的效果。
- m_dcBuffer.TransparentBlt((m_coor_y-m_b)/m_k,m_coor_y,80,105,&m_dcImage,80*2,4*105,80,105,RGB(255,0,255));
m_dcBuffer.TransparentBlt((m_coor_y-m_b)/m_k,m_coor_y,80,105,&m_dcImage,80*2,4*105,80,105,RGB(255,0,255));
最後我們只需要設置一個定時器,每隔一段時間來更新Y值就可以了。
當在更新的時候P點到達A,B,C任何一個點時,將牌的座標存入相應的vector中,繪製的時候根據VECTOR的值來繪製3方的牌就可以了。
地主洗牌實現:
首先上一張圖片
大家知道玩鬥地主的時候有54張牌嗎?如果知道,那很好,你可以進入下面的環節了。分析分牌思路。
首先我們可以定義一個擁有54張牌的一維數組。
int CardValueArray[54];
注意:詳細理解下面的意思,這個對分牌很重要的。我們將54個元素用來代表不同的牌。
CardValueArray[0——–12]: 方塊A———方塊K
CardValueArray[13——–25]: 梅花A———梅花K
CardValueArray[26——-38-]: 紅心A———紅心K
CardValueArray[39——–51]: 黑桃A———黑桃K
CardValueArray【52】 小鬼 CardValueArray【53】大鬼
我想你現在應該明白我接下來該怎麼做了吧!(嘿嘿)
我們將CardValueArray[54] 依次初始化爲0——53.然後打亂數組的值,將數組分爲4份。3份17張,1份3張(槍地主牌牌)。將3份17張牌,依次分發給3個不同的玩家。
這裏難點就是給數組賦值。
這裏有很多種方法。
第一種:
我們最直接能想到的一種,也是效率最低的方法。 也是我程序中採用的方法。(呵呵,比較笨吧!)
定義一個擁有54個元素的一維數組賦值爲-1。然後隨機生成0——54之間的數,然後判斷生成的數是否在數組中已存在,不存在則存入數組,已存在則重新生成,直到54個數全部出現爲止。
第二種:
可以這樣,比如,定義一個擁有54個元素的一維數,依次賦值爲1——53,然後隨機兩個0-53的數字,把這兩個位置的數字互換 這樣做比較多的次數之後,也是亂序的了,這個效率也不是特別高,但是比第一種要強。
第三種做法:
定義一個擁有54個元素的一維數,依次賦值爲1——53, 隨機54次,每次隨機出一個數字,和第i個位置的數字交換,這樣就比較不錯了
- int CardValueArray[54];
- for(int i=0;i<54;i++)
- {
- CardValueArray[i]=i;
- }
- for (int i=0;i<54;i++)
- {
- swap( CardValueArray[i], CardValueArray[(rand()%54)]);
- }
int CardValueArray[54];
for(int i=0;i<54;i++)
{
CardValueArray[i]=i;
}
for (int i=0;i<54;i++)
{
swap( CardValueArray[i], CardValueArray[(rand()%54)]);
}
比如說,先隨機出一個位置,和第一個數字交換,然後隨機出一個位置,和第二個數字交換 打個比方,先隨機出10,然後第十個數字,和第一個數字交換 然後隨機出一個12,第12個數字,和第2個數字交換 然後隨機一個數字和第三個交換.
第四種:
使用rand_shuffle隨機化序列元素。
c++中提供了更好的解決方法,那就是random_shuffle()算法。不要着急,下面我就會告訴你如何用這種算法來產生不同類型的隨機數。
產生指定範圍內的隨機元素集的最佳方法是創建一個順序序列(也就是向量或者內置數組),在這個順序序列中含有指定範圍的所有值。例如,如何你需要產生54個0-54之間的數,那麼就創建一個向量並用54個按升序排列的數填充向量:
- #include <vector> using std::vector;
- int main()
- {
- vector<int> vi;
- for (int i = 0; i < 10; i++)
- {
- vi.push_back(i); /*現在向量包含了54個 0-54 之間的整數並且按升序排列*/
- }
#include <vector> using std::vector;
int main()
{
vector<int> vi;
for (int i = 0; i < 10; i++)
{
vi.push_back(i); /*現在向量包含了54個 0-54 之間的整數並且按升序排列*/
}
填充完向量之後,用random_shuffle()算法打亂元素排列順序。random_shuffle()定義在標準的頭文件<algorithm.h>中。因爲
所有的STL算法都是在名字空間std::中聲明的,所以你要注意正確地聲明數據類型。random_shuffle()有兩個參數,第一個參數是指向序列首元素的迭代器,第二個參數則指向序列最後一個元素的下一個位置。下列代碼段用random_shuffle()算法打亂了先前填充到向量中的元素:
- <span style=“FONT-SIZE: 16px”> #include <algorithm>
- using std::random_shuffle;
- random_shuffle(vi.begin(), vi.end()); /* 打亂元素 */
- </span>
<span style="FONT-SIZE: 16px"> #include <algorithm>
using std::random_shuffle;
random_shuffle(vi.begin(), vi.end()); /* 打亂元素 */
</span>
你可以選擇以上4種中的任何一種方法來生成54個0–54之間的不重複數。
這樣我們 通過以上的方法就將CardValueArray數組中的值賦值上了。現在我們只需要用數組中的值到大圖中切對應的牌就行了。
從上圖中我們可以用一個公式來表示每張牌在大圖中的,X,Y座標即:
x=CardValueArray[i]%13*每張牌的寬
y=CardValueArray[i]/13*每張牌的高
轉載自 http://blog.csdn.net/wojiushi3344/article/details/7522245