#include <iostream>
#include <conio.h>
#include <time.h>
using namespace std;
#define MAX_LEN 54
#define SEND_END 0
#define SEND_NOT_END 1
#define CARD_NUM 20
//斗牛程序的一些说明:
//n / 4 表示这个牌的数值 + 1
//n % 4 == 0:黑桃 1:红桃 2:梅花 3:方块
//n == 52 小王
//n == 53 大王
//当数组中的数值存储为1表示此牌已经发出;如果为0表示没有发出
//因为斗牛不需要大王和小王所以所以在出示话的时候将52,53位设置为1
//默认A组为庄家
//设置参与人数为4
//数组初始化为0
void Input(int* arr, int nLen);
//得到一张牌
void GetNum(int* arr, int nLen, int* a);
//发 n 张牌
int SendCard(int* arr, int nLen, int* pn, int nLen2);
//打印一张牌
void PrintCard(int a);
//打印 n 张牌, 并比较牛数大小
void Output(int* pn, int nLen);
//获取一组数据的牛数
//通过返回值返回
int GetNiu(int* pn); //nLen == 5
//比较两组数的牛数大小
int CompareNiu(int *pn1, int* pn2);
//从新定向数值为对应的牛数计算数值
void ReDirectNum(int* pn);
//将数组排成有序函数
void Sort(int* pn, int nLen);
//获取数组中最大的数值
int GetMax(int* pn, int nLen);
int main()
{
int nArr[MAX_LEN] = {0};
int narrCard[CARD_NUM] = {0};
int nLen = 0;
int nRet = 0;
char ch = '0';
//获取真真的随机数
srand(time(NULL));
//初始化的工作
Input(nArr, MAX_LEN);
//开始发牌,并比较与庄家的牛数大小
while (true)
{
cout << "按任意键开始游戏..." << endl;
getch();
nRet = SendCard(nArr, MAX_LEN, narrCard, CARD_NUM);
if (SEND_END == nRet)
{
cout << endl << endl;
cout << "----------------------------------------" << endl;
cout << "牌已经发完了,是否重新开始游戏?" << endl;
cout << "----------------------------------------" << endl;
cin >> ch;
if ( ('n' == ch) || ('N' == ch) )
{
break;
}
else
{
//初始化的工作
Input(nArr, MAX_LEN);
}
}
else
{
Output(narrCard, CARD_NUM);
}
}
return 0;
}
void Input(int* arr, int nLen)
{
int i = 0;
for (i = 0; i < nLen; i++)
{
arr[i] = 0;
}
//当数组中的数值存储为1表示此牌已经发出;如果为0表示没有发出
//因为斗牛不需要大王和小王所以所以在出示话的时候将52,53位设置为1
arr[MAX_LEN - 1] = 1;
arr[MAX_LEN - 2] = 1;
}
int SendCard(int* arr, int nLen, int* pn, int nCardNum)
{
//4个人得到20张牌
int i = 0;
for (i = 0; i < nCardNum; i++)
{
GetNum(arr, nLen, pn + i);
if (-1 == *(pn + i))
{
return SEND_END;
}
}
return SEND_NOT_END;
}
void GetNum(int* arr, int nLen, int* a)
{
int i = 0;
while (true)
{
*a = rand() % 54;
if (1 == arr[*a])
{
for (i = 0;i < nLen; i++)
{
if (1 != arr[i])
{
break;
}
}
if (i < nLen)
{
continue;
}
else
{
*a = -1;
break;
}
}
else
{
arr[*a] = 1;
break;
}
}
}
//打印 n 张牌
void Output(int* pn, int nLen)
{
int i = 0;
int j = 0;
int n = 0;
//输出A组: 庄家 0 ~ 4
for (i = 0; i < 5; i++)
{
PrintCard(*(pn + i));
}
//输出庄家牛数
cout <<"----------------------------------------------------------------"<< endl;
cout << "庄家: 牛" << GetNiu(pn) << endl;
cout <<"----------------------------------------------------------------"<< endl;
cout << endl << endl;
//输入其他的闲家
for (j = 0; j < 3; j++)
{
for (i = 0; i < 5; i++)
{
n = *(pn + (j + 1) * 5 + i);
PrintCard(n);
}
cout <<"----------------------------------------------------------------"<< endl;
cout << "闲家" << j + 1 << ": 牛" << GetNiu(pn + (j + 1) * 5) << endl;
cout <<"----------------------------------------------------------------"<< endl;
if (1 == CompareNiu(pn, pn + (j + 1) * 5))
{
cout << "对不起, 您输了!" << endl;
}
else
{
cout << "恭喜,您赢了!" << endl;
}
cout << endl << endl;
}
}
//获取一组数据的牛数
//通过返回值返回
int GetNiu(int* pnArr) //nLen == 5
{
int pn[5];
int i = 0;
int j = 0;
int k = 0;
int sum = 0;
//备份数值,否则破坏了传入的数据
for (i = 0; i < 5; i++)
{
pn[i] = pnArr[i];
}
//数值转换
for (i = 0; i < 5; i++)
{
ReDirectNum(pn + i);
}
//求牛数
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (i == j)
{
continue;
}
for (k = 0; k < 5; k++)
{
if ( (k == i) || (k == j) )
{
continue;
}
sum = *(pn + i) + *(pn + j) + *(pn + k);
if (sum % 10 == 0)
{
goto end;
}
}
}
}
end:
//表示不存在3张牌之和是10的倍数
if (i == 5)
{
return 0;
}
sum = 0;
for (i = 0; i < 5; i++)
{
sum += *(pn + i);
}
//判断是否是牛王
if (sum % 10 == 0)
{
return 10;
}
return sum % 10;
}
//从新定向数值为对应的牛数计算数值
void ReDirectNum(int* pn)
{
*pn = *pn / 4 + 1;
if (*pn > 10)
{
*pn = 10;
}
}
//比较两组数的牛数大小
//返回值: 1 表示:pn1 > pn2
//返回值: 0 表示:pn1 < pn2
int CompareNiu(int *pn1, int* pn2)
{
int n1 = 0;
int n2 = 0;
//判断牛数是否相等
n1 = GetNiu(pn1);
n2 = GetNiu(pn2);
if (n1 < n2)
{
return 0;
}
else if (n1 > n2)
{
return 1;
}
//如果不是以上两种情况,说明 n1 == n2
//这也就是说明牛数相同
n1 = GetMax(pn1, 5);
n2 = GetMax(pn2, 5);
if (n1 < n2)
{
return 0;
}
else
{
return 1;
}
}
//获取数组中最大的数值
int GetMax(int* pn, int nLen)
{
int nMax = 0;
int i = 0;
for (i = 0; i < nLen; i++)
{
if (pn[i] > nMax)
{
nMax = pn[i];
}
}
return nMax;
}
//将数组排成有序函数
void Sort(int* pn, int nLen)
{
int i = 0;
int j = 0;
int nTemp = 0;
for (i = 0; i < 5; i++)
{
for (j = i + 1; j < 5; j++)
{
if (pn[i] < pn[j])
{
nTemp = pn[i];
pn[i] = pn[j];
pn[j] = nTemp;
}
}
}
}
void PrintCard(int a)
{
int n = 0;
char ch = '/0';
if (-1 == a)
{
cout << "没有牌" << endl;
return;
}
if (53 == a)
{
cout << "大王" << endl;
}
else if (52 == a)
{
cout << "小王" << endl;
}
else
{
switch (a % 4)
{
case 0:
cout << "黑桃";
break;
case 1:
cout << "红桃";
break;
case 2:
cout << "梅花";
break;
case 3:
cout << "方块";
break;
default:
cout << "error";
break;
}
n = a / 4 + 1;
switch (n)
{
case 1:
ch = 'A';
break;
case 11:
ch = 'J';
break;
case 12:
ch = 'Q';
break;
case 13:
ch = 'K';
break;
default:
cout << n << endl;
return;
}
cout << ch << endl;
}
}