前边一篇文章介绍了斗地主一般的发牌思路,今天我就分享一下有点难度的的分配发牌算法,欢迎各位提意见!
需求是这样的:每局3个玩家手中至少有一个玩家手中有一个炸弹并且是随机发出的。
解决思路是这样的:
其实54张牌我们可以定义成一个这样的数组如下(其中元素为十六进制的数,括号内为十进制数)
static int card_arr[] = {
0x01(1 方块A), 0x11(17 梅花), 0x21(33 红桃), 0x31(49 黑桃), //A
0x02(2 方块2), 0x12(18 梅花), 0x22(34 红桃), 0x32(50 黑桃), //2
0x03(3 方块3), 0x13(19 梅花), 0x23(35 红桃), 0x33(51 黑桃), //3
0x04(4 方块4), 0x14(20 梅花), 0x24(36 红桃), 0x34(52 黑桃), //4
0x05(5 方块5), 0x15(21 梅花), 0x25(37 红桃), 0x35(53 黑桃), //5
0x06(6 方块6), 0x16(22 梅花), 0x26(38 红桃), 0x36(54 黑桃), //6
0x07(7 方块7), 0x17(23 梅花), 0x27(39 红桃), 0x37(55 黑桃), //7
0x08(8 方块8), 0x18(24 梅花), 0x28(40 红桃), 0x38(56 黑桃), //8
0x09(9 方块9), 0x19(25 梅花), 0x29(41 红桃), 0x39(57 黑桃), //9
0x0A(10 方块10), 0x1A(26 梅花), 0x2A(42 红桃), 0x3A(58 黑桃), //10
0x0B(11 方块J), 0x1B(27 梅花), 0x2B(43 红桃), 0x3B(59 黑桃), //J
0x0C(12 方块Q), 0x1C(28 梅花), 0x2C(44 红桃), 0x3C(60 黑桃), //Q
0x0D(13 方块K), 0x1D(29 梅花), 0x2D(45 红桃), 0x3D(61 黑桃), //K
0x0E(14小王), 0x0F(15大王)
};
54张牌有了,下边我们针对这样的一副牌可以看出:1-13个数字就可以代表A-K了,所以我们就可以以这为基数,留下炸弹牌的基数,那么他另外的三张同值牌也就有了。
用一句来说也就是:先随机出1-N个炸弹,将炸弹的基数预留出来,在随机出每个玩家应该分配的炸弹数,把炸弹发给玩家,后其他牌随机发出即可。
下边请看具体代码:
/*************************************************************************/
/***********斗地主发牌逻辑中级算法****************************************/
/*************************************************************************/
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
?// 定义在该标准头文件中random_shuffle()定义在标准的头文件
中。 //因为所有的STL算法都是在名字空间std::中声明的?所以你要注意正确地声 //明数据类型。random_shuffle()有两个参数?第一个参数是指向序列首元 //素的迭代器?第二个参数则指向序列最后一个元素的下一个位置。 using namespace std; void main() {
//存储54张牌的数组
int card_arr[54] ={1,17,33,49,2,18,34,50,3,19,35,51,4,20,36,52,5,21,37,53,6,22,38,54,7,23,39,55,8,24,40,56,9,25,41,57,
10,26,42,58,11,27,43,59,12,28,44,60,13,29,45,61,14,15};
srand(time(NULL) + 1); //初始化随机数发送器 设置随机函数的启动数值
int bomb_num = rand() % 3;
if (bomb_num == 0){
bomb_num =2;
}
//创建3个vector容器来装牌,注意容器是先进先出的。
vector
new_arr_
vc;
vector
other_card_vc;
vector
last_all_cards;
new_arr_vc.clear(); // 装炸弹基数牌
other_card_vc.clear();// 装除炸弹之外的牌
last_all_cards.clear();// 装所有洗好的牌
//new_arr_vc 0-12 共13个数字(玩家炸弹基数)
for (int i = 0; i < 13; i++){
new_arr_vc.push_back(i);
}
random_shuffle(new_arr_vc.begin(), new_arr_vc.end()); //随机函数 将其打乱
for (int i = 12; i >=0; i--){
cout<
}
cout<
// 假设当炸弹数目为一个时 other_card_vc.size= (13-1)*4 =48 留四张牌凑一个炸弹 ? ? // 假设当炸弹数目为两个时 other_card_vc.size= (13-2)*4 =44 留八张牌凑两个炸弹
int othersize = 0; //调试时牌打印所用
for (int i = 0; i< 13 - bomb_num; i++){
for(int k=0; k < 4; k++){
other_card_vc.push_back(card_arr[new_arr_vc[bomb_num+i]*4+k]);//new_arr_vc[bomb_num+i] 跳过要保留为炸弹基数的牌值
cout<
othersize++;
}
cout<
}
cout<
cout<
other_card_vc.push_back(card_arr[52]); // 加入小王
other_card_vc.push_back(card_arr[53]); // 加入大王
random_shuffle(other_card_vc.begin(), other_card_vc.end()); //随机函数 将其打乱
cout<
// 随机玩家炸弹数
unsigned int b_num1 ?= 0;
unsigned int b_num2 ?= 0;?
unsigned int b_num3 ?= 0;
int flag = rand() % 3;
switch(bomb_num) ? ? {
case 0:
b_num1 ?= 0;
b_num2 ?= 0;?
b_num3 ?= 0;
break;
case 1:
if (flag == 0){
b_num1 ?= 1;
b_num2 ?= 0;?
b_num3 ?= 0;
}else if (flag == 1){
b_num1 ?= 0;
b_num2 ?= 1;?
b_num3 ?= 0;
}else{
b_num1 ?= 0;
b_num2 ?= 0;?
b_num3 ?= 1;
}
break;
case 2:
if (flag == 0){
b_num1
= rand() % ?3;
b_num2
= rand() % ?3;
if (b_num1 + b_num2 >= 3){
b_num1--;
b_num2--;
}
b_num3 = bomb_num - b_num1 - b_num2;
}e