扑克牌。使用一副去掉大小王的扑克牌,共52张牌。 2-4人, 可只支持固定人数,每人三张牌,比大小牌型,
由大到小分别为:。
1)同花顺:花色相同的顺子,黑桃456.红桃A23.。
(2)三张:三张点相同的牌,AAA. 222
3)顺子,花色不完全相同的顺子,黑桃5红桃6方片7。 “
(4)同色:花色相同,非顺子,黑桃368, 方片945.。
(5) 对子:对子:带有两张点相同的牌,223, 334.
(6) 散排,三张牌不组成以上任何类型的牌。。
牌点从大到小依次为,A. K、Q、J10.9.8.7.6、5.4.3.2.先比牌型,牌型靠前面的胜:同样牌型则比牌点大小。
例如。 ” (1)甲,同色,乙:对子,甲胜(花色靠前的花色大)。
(2甲,对223. 乙对子334.乙胜(对子大),
3)甲, 对子885乙:对子884.甲胜(对子相等,单牌大),
4)甲,散牌087.乙散牌094.乙胜(最大牌相等,第二大牌大)“
可以用规则复杂度高于上述要求的某种朴克牌打法完成扑克牌程序。
花色大小顺序:黑、红、方、梅
#include<stdlib.h>
#include<time.h>
#include <stdio.h>
//花色
typedef enum _HUASE
{
MEIHUA = 0,
FANGKUAI = 1,
HONGTAO = 2,
HEITAO = 3
}HUASE;
//牌型
typedef enum _PUKETYPE
{
ZP = 0, //杂牌
DZ = 1, //对子
TH = 2, //同花
SZ = 3, //顺子
TN = 4, //三张
THS = 5 //同花顺
}PUKETYPE;
typedef struct _PUKE
{
unsigned short num;
HUASE huase;
}PUKE;
class person
{
private:
PUKE p[3];
PUKETYPE pukeType;
void calcType()//计算牌力
{
if(p[0].num == p[1].num)
{
if(p[1].num == p[2].num)
pukeType = TN; //三张相同,三张
else
pukeType = DZ; //两张相同,对子
}
else if(p[1].num == p[2].num) //两张相同,对子
pukeType = DZ;
else //三张都不相同的情况,先比较是否顺子,再比较是否同花
{
//特例判定,不符合递减顺序的顺子
if(p[0].num == 14 && p[1].num == 3 && p[2].num == 2)
{
if(p[0].huase != p[1].huase || p[1].huase != p[2].huase)
pukeType = SZ;
else
pukeType = THS;
}
else if((p[0].num - p[1].num)==1 && (p[1].num - p[2].num)== 1) //如果递减排序
{
if(p[0].huase != p[1].huase || p[1].huase != p[2].huase)
pukeType = SZ;
else
pukeType = THS;
}
else if(p[0].huase == p[1].huase && p[1].huase == p[2].huase) //如果花色相同为同花
{
pukeType = TH;
}
else
pukeType = ZP;
}
//
}
public:
person() {}
~person() {}
PUKETYPE GetPukeType() { return pukeType; }
PUKE *GetPuke() { return p; }
unsigned short GetDZ(PUKE &ZP) //当牌力为对子时,获取对子牌点数,同时返回剩余的杂牌,便于比较
{//因为牌已经排序,所以要么前两张相同,要么后两张相同
if(p[0].num == p[1].num)
{
ZP = p[2];
return p[0].num;
}
ZP = p[0];
return p[1].num;
}
void SetPuke(PUKE pk[3])
{
for (int n = 0; n < 3; n++)
p[n] = pk[n];
//对三张牌进行从大到小排序
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
if (p[j].num < p[j + 1].num)
{
PUKE puke = p[j];
p[j] = p[j + 1];
p[j + 1] = puke;
}
//牌点数相同时,进行花色排序
else if (p[j].num == p[j + 1].num)
{
if (p[j].huase < p[j + 1].huase)
{
PUKE puke = p[j];
p[j] = p[j + 1];
p[j + 1] = puke;
}
}
}
}
//计算牌力
calcType();
}
void ShowPukeType()
{
switch (pukeType)
{
case THS:
printf("同花顺");
break;
case TN:
printf("三张");
break;
case SZ:
printf("顺子");
break;
case TH:
printf("同花");
break;
case DZ:
printf("对子");
break;
case ZP:
printf("杂牌");
break;
}
}
void ShowPuke()
{
for (int i = 0; i < 3; i++)
{
switch (p[i].huase)
{
case MEIHUA:
printf("梅花");
break;
case FANGKUAI:
printf("方块");
break;
case HONGTAO:
printf("红桃");
break;
case HEITAO:
printf("黑桃");
break;
}
if (p[i].num >= 2 && p[i].num <= 10)
printf("%d\t", p[i].num);
else if (p[i].num == 11)
printf("J\t");
else if (p[i].num == 12)
printf("Q\t");
else if (p[i].num == 13)
printf("K\t");
else if (p[i].num == 14)
printf("A\t");
if (i < 2)
printf(" ");
}
}
bool operator > (person &ps)
{
//如果牌力不同,直接出结果
if (pukeType > ps.GetPukeType())
return true;
//如果牌力相同,根据不同牌力进行比较
else if (pukeType == ps.GetPukeType())
{
PUKE *puke = ps.GetPuke();
switch (pukeType)
{
case THS: //如果都是同花顺,则比较最大牌的大小
case SZ: //如果都是顺子,与同花顺的比较相同
{
if (p[0].num > puke[0].num) //先比较最大牌大小
return true;
else if (p[0].num > puke[0].num) //如果最大牌大小相同,比较最大牌花色(花色不可能相同)
return p[0].huase > puke[0].huase;
}
break;
case TN: //如果都是三张,则只需要比较牌大小,不可能相同
return p[0].num > puke[0].num;
break;
case TH: //如果都是同花,则先比较牌大小,当牌完全相同时,再比较最大牌花色
case ZP: //如果都是杂牌,与同花的比较相同
{
//逐张牌比较大小
if(p[0].num != puke[0].num)
return p[0].num > puke[0].num;
else if(p[1].num != puke[1].num)
return p[1].num > puke[1].num;
else if(p[2].num != puke[2].num)
return p[2].num > puke[2].num;
else if (p[0].num > puke[0].num) //如果最大牌大小相同,比较最大牌花色(花色不可能相同)
return p[0].huase > puke[0].huase;
}
break;
case DZ: //对子
{
PUKE ZP1,ZP2;
unsigned short DZ1,DZ2;
DZ1 = GetDZ(ZP1);
DZ2 = ps.GetDZ(ZP2);
if(DZ1 == DZ2) //如果对子相同,则比较杂牌
{
if(ZP1.num == ZP2.num) //如果杂牌点数相同,则比较花色
return ZP1.huase > ZP2.huase;
else
return ZP1.num > ZP2.num;
}
else
return DZ1 > DZ2;
}
break;
}
}
return false;
}
};
int main()
{
while (true)
{
bool bUse[4][13] = { 0 };
int n, i, m, num;
HUASE hs;
PUKE pk[3];
printf("请输入玩游戏人数(2-4):");
scanf_s("%d", &n);
if(n>4 || n<2)
{
printf("游戏人数必须是2-4个,请重新输入\n");
continue;
}
printf("\n");
//
person *ps = new person[n];
srand((unsigned)time(NULL));
for (i = 0; i < n; i++)
{
m = 0;
while (m < 3)
{
hs = (HUASE)(rand() % 4);
num = rand() % 13;
if (!bUse[hs][num])
{
bUse[hs][num] = true;
pk[m].huase = hs;
pk[m].num = num + 2;
m++;
}
}
ps[i].SetPuke(pk);
}
int winpos = 0;
for (i = 0; i < n; i++)
{
printf("%d号牌手的三张牌为: \t",i+1);
ps[i].ShowPuke();
printf("\t牌型为:");
ps[i].ShowPukeType();
printf("\n");
if(i<n-1)
{
if(ps[i+1] > ps[winpos])
{
winpos = i+1;
}
}
}
printf("\n恭喜本局%d号牌手以 ",winpos+1);
ps[winpos].ShowPukeType();
printf(" 获胜!\n");
//
delete []ps;
ps = NULL;
printf("\n再来一局?(N键退出,其它键继续):");
getchar();
char ch;
scanf_s("%c", &ch,1);
if (ch == 'N' || ch=='n')
break;
}
return 0;
}