前言:欢迎转载,但请注明出处http://blog.csdn.net/jiadabin,因为原文可能会改动部分不足,最好从原文处阅读,同时也欢迎大家来点评丶吐槽!让我们大家共同进步......
前边一篇文章介绍了斗地主一般的发牌思路,今天我就分享一下有点难度的的分配发牌算法,欢迎各位提意见!
需求是这样的:每局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<= 3){
b_num1--;
b_num2--;
}
b_num3 = bomb_num - b_num1 - b_num2;
}else if (flag == 1){
b_num1 = rand() % 3;
b_num3 = rand() % 3;
if (b_num1 + b_num3 >= 3){
b_num1--;
b_num3--;
}
b_num2 = bomb_num - b_num1 - b_num3;
}else{
b_num2 = rand() % 3;
b_num3 = rand() % 3;
if (b_num2 + b_num3 >= 3){
b_num2--;
b_num3--;
}
b_num1 = bomb_num - b_num2 - b_num3;
}
break;
case 3:
if (flag == 0){
b_num1 = rand() % 4;
b_num2 = rand() % 4;
if (b_num1 + b_num2>=4 && b_num1 + b_num2<=5){
b_num1--;
b_num2--;
}else if (b_num1 + b_num2 >= 6){
b_num1 = b_num1 - 2;
b_num2 = b_num2 - 2;
}else{
//....
}
b_num3 = bomb_num - b_num1 - b_num2;
}else if (flag == 1){
b_num1 = rand() % 4;
b_num3 = rand() % 4;
if (b_num1 + b_num3>=4 && b_num1 + b_num3<=5){
b_num1--;
b_num3--;
}else if (b_num1 + b_num3 >= 6){
b_num1 = b_num1 - 2;
b_num3 = b_num3 - 2;
}else{
//....
}
b_num2 = bomb_num - b_num1 - b_num3;
}else{
b_num2 = rand() % 4;
b_num3 = rand() % 4;
if (b_num2 + b_num3>=4 && b_num2 + b_num3<=5){
b_num2--;
b_num3--;
}else if (b_num2 + b_num3 >= 6){
b_num2 = b_num2 - 2;
b_num3 = b_num3 - 2;
}else{
//....
}
b_num1 = bomb_num - b_num2 - b_num3;
}
break;
default:
break;
}
// 打印3个玩家分配到的炸弹数
cout<= 17 && last_all_cards.size() < 34){
// 该判断是为了预留出炸弹的位置
if (last_all_cards.size() < b_num2 * 4 + 17){
// 满足条件分配炸弹
for (int j = 0; j < 4; j++){
last_all_cards.push_back(card_arr[new_arr_vc[bomb_tmp] * 4 + j]);
cout<= 34 && last_all_cards.size() < 51){
// 该判断是为了预留出炸弹的位置
if (last_all_cards.size() < b_num3 * 4 + 34){
// 满足条件分配炸弹
for (int j = 0; j < 4; j++){
last_all_cards.push_back(card_arr[new_arr_vc[bomb_tmp] * 4 + j]);
cout<
测试部分效果如下:有不明白的也可以问我,有更好的方法的可以吐槽,大家互相学习,谢谢!