C语言Poker扑克牌(炸金花)

背景:两个人每人发3张牌(各从一副牌中),每张牌包括花色(红桃(Heart)>黑桃(Spade)>方块(Diamond)>梅花(Club))和大小(从小到大依次是:2-10、J、Q、K、A),胜负规则如下:同花顺(3张同花色的连牌,先比大小,再比花色后同)>炸弹(3张相同大小的牌)>连牌(3张不同花色的连牌)>对子(两张相同大小的牌)>单牌。例如,红桃QKA>黑桃QKA>梅花567>方块234>AAA(红桃、方块、梅花)>AAA(黑桃、方块、梅花)>JQK(红桃、红桃、方块)>JQK(黑桃、红桃、方块)>AA2(梅花黑桃梅花)>QQJ(红桃梅花方块)>JQA(红桃红桃红桃)。注:A23不算连牌。

输入:A的3张牌(未排序)和B的3张牌(未排序)。(参见用例)

输出:A的3张牌的排序后的输出和B的3张牌的排序后的输出,以及A和B谁获胜。(参见用例)

 

这道题的输入处理起来不是很方便,考虑到扑克牌中的10,我们得用一个三元字符数组存储一张牌,同时得存储每一个人的三张牌。

考虑到每个人的牌都是从一副完整牌组中取得,因此不存在两张完全相同的牌。据此,我们可以写出两个函数检验输入是否合理。check1检验花色,check2检验点数。

 

 用一个循环处理输入,每次输入三个字符,除10以外的牌都包含了空格。单独考虑10的情况,需要额外取出一个空格。同时考虑到之后要对点数进行比较,可以先把10转化为‘9’后一个。

我们设置一个标志error记录输入情况。

 b的输入类似。

 如果输入错误,直接输出结果。接下来考虑有效输入。

由于需要判断顺子等牌型,我们对点数进行调整使满足连贯性。

 同时我们要比较每张牌的大小,根据点数优先写出比较函数。

注意,此处对红桃进行升格处理,是利用花色ASCII码的特性(要求H>S>D>C),可以根据个人喜好合理调整。

 利用cmp2函数写出如下的冒泡排序函数。

 考虑到比较大小时牌型优先级最高,由大到小排序后我们写出判断牌型的函数。

 由于以上函数调用传递的都是指针变量,并且对其指向的值做了一定修改,我们在输出时应提前复原。

 最后比较大小按要求输出即可。

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
int check1(char);
int check2(char);
int cmp(char a[2],char b[2]);
int cmp2(char a[],char b[]);
void sort2(char a[3][3]);
void restore(char a[2]);
void change(char a[3][3]);
int card_type(char a[3][3]);
enum kind {straight_flush,three,straight,pair,single};
int main()
{
    char a[3][3]={0},b[3][3]={0};
    int i=0,j=0,error=0,flag;
    for(i=0;i<3;i++)//input and check
    {
        scanf("%c%c%c",&a[i][0],&a[i][1],&a[i][2]);
        if(a[i][2]=='0'){a[i][1]='9'+1;a[i][2]=0;if(i!=2)scanf(" ");}//输入有10,化为两位
        if(check1(a[i][0])&&check2(a[i][1]))continue;
        else 
        {
            error=1;
            break;
        }
    }
    scanf("\n");
    for(i=0;i<3;i++)
    {
        scanf("%c%c%c",&b[i][0],&b[i][1],&b[i][2]);
        if(b[i][2]=='0'){b[i][1]='9'+1;b[i][2]=0;if(i!=2)scanf(" ");}
        if(check1(b[i][0])&&check2(b[i][1]))continue;
        else 
        {
            error=1;
            break;
        }
    }
    for(i=0;i<2;i++)//检查重复
    {
      for(j=i+1;j<3;j++)
      {
        if((a[i][0]==a[j][0]&&a[i][1]==a[j][1])
        ||(b[i][0]==b[j][0]&&b[i][1]==b[j][1]))error=1;
      }
    }
    if(error)printf("Input Error!\n");
    else//valid input
    {
       change(a);change(b);//adjust the point
       sort2(a);sort2(b);//sort
       if(card_type(a)<card_type(b))flag=1;//a牌型大
       else if(card_type(a)>card_type(b))flag=3;//a牌型小
       else//同种牌型
       {
         for(i=0;i<3;i++)
         {
            if(cmp2(a[i],b[i])==1){flag=1;break;}
            else if(cmp2(a[i],b[i])==3){flag=3;break;}
            else {flag=2;continue;}
         }
       }
        if(flag==1)
        {
            printf("Winner is A!\nA:");
        }
       else if(flag==2)
       {
         //printf("Winner is X!\nA:");
         printf("Draw!\nA:");
       }
       else if(flag==3)
       {
        printf("Winner is B!\nA:");
       }
       for(i=0;i<3;i++)//恢复
       {restore(a[i]);restore(b[i]);}
       for(i=0;i<3;i++)
        {
            if(a[i][2]=='0')printf(" %c%c%c",a[i][0],a[i][1],a[i][2]);
            else printf(" %c%c",a[i][0],a[i][1]);
        }
        printf("\nB:");
        for(i=0;i<3;i++)
        {
            if(b[i][2]=='0')printf(" %c%c%c",b[i][0],b[i][1],b[i][2]);
            else printf(" %c%c",b[i][0],b[i][1]);
        }
        putchar(10);
    }
    system("pause");
    return 0;
}
int check1(char card)//check the suits
{
   if(card!='H'&&card!='S'&&card!='D'&&card!='C')return 0;//ERROR
   else return 1;
}
int check2(char card)//check the points
{
    if(('2'<=card&&card<='9'+1)||card=='J'||card=='Q'||card=='K'||card=='A')return 1;
    else return 0;
}
int cmp(char a[2],char b[2])//花色优先//if the first is bigger,return 1;else if equal,return 2;else return 3
{
    if(a[0]=='H')a[0]='T';if(b[0]=='H')b[0]='T';//给红桃升格
    if(a[0]>b[0])return 1;
    else if(a[0]==b[0])//the suit is the same
    {
        if(a[1]>b[1])return 1;
        else if(a[1]==b[1])return 2;
        else return 3;
    }
    else return 3;
}
int cmp2(char a[],char b[])//点数优先
{
    if(a[0]=='H')a[0]='T';if(b[0]=='H')b[0]='T';//给红桃升格
    if(a[1]>b[1])return 1;
    else if(a[1]<b[1])return 3;
    else
    {
        if(a[0]>b[0])return 1;
        else if(a[0]<b[0])return 3;
        else return 2;
    }
}
void change(char a[3][3])//adjust the point
{
    int i,j;
    for(i=0;i<3;i++)
    {
        //if(a[i][1]=='1'&&a[i][2]=='0'){a[i][1]='9'+1;a[i][2]=0;}
        if(a[i][1]=='J')a[i][1]='9'+2;
        else if(a[i][1]=='Q')a[i][1]='9'+3;
        else if(a[i][1]=='K')a[i][1]='9'+4;
        else if(a[i][1]=='A')a[i][1]='9'+5;
    }
}
void sort2(char a[3][3])
{
   int i,j;char t1,t2;
   for(i=0;i<2;i++)
   {
    for(j=0;j<2-i;j++)
    {
    if(cmp2(a[j],a[j+1])==3)
    {
        t1=a[j][0];t2=a[j][1];
        a[j][0]=a[j+1][0];a[j][1]=a[j+1][1];
        a[j+1][0]=t1;a[j+1][1]=t2;
    }
    }
   }
}
void restore(char a[])//由于传递指针改变原值应恢复
{
    if(a[0]=='T')a[0]='H';//给红桃升格
    if(a[1]=='9'+1){a[1]='1';a[2]='0';}
    else if(a[1]=='9'+2)a[1]='J';
    else if(a[1]=='9'+3)a[1]='Q';
    else if(a[1]=='9'+4)a[1]='K';
    else if(a[1]=='9'+5)a[1]='A';
}
int card_type(char a[3][3])//排序后判断牌型
{
   if(a[0][0]==a[1][0]&&a[1][0]==a[2][0]&&//同花
   a[0][1]==a[1][1]+1&&a[1][1]==a[2][1]+1)//顺
   return 0;
   else if(a[0][1]==a[1][1]&&a[1][1]==a[2][1])return 1;//three of a kind
   else if(a[0][1]==a[1][1]+1&&a[1][1]==a[2][1]+1)return 2;//straight
   else if(a[0][1]==a[1][1]||a[0][1]==a[2][1]||a[1][1]==a[2][1])return 3;//pair
   else return 4;//single
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值