扑克游戏(函数规范化,拆分事件)

前言:

题目链接
进入链接后,点击实践项目,以下两道题分别为6.8.15和6.8.16,

这两道题算不上难,特别是第二道在之前某个比赛中遇到过一次,当时没做出来,想着去找的,没找着,现在又看到了不免兴致冲冲( ̄︶ ̄)↗ ,狠狠报仇了也是,虽然究到底只是道排序题,不过条件特别多,写起来就会觉得很麻烦了

扑克游戏1

任务描述
老师给X同学留了一个任务:扑克游戏中的牌型判断。

输入格式:

输入的第一行,是一个整数N,表示有N组数据。
接下来的N行是N组数据,每一行数据有3张扑克牌,
例如:5S 6H 12C,其中数字表示点数(2-10分别代表2点到10点的牌,14代表A,11、12、13代表J、Q、K),
字母表示花色的第一个字符,黑桃(Spade)、红桃(Heart)、梅花(Club)、方块(Diamond)。
以上3张牌为黑桃5、红桃6、方块Q。

输出格式:

输出N行,每一行输出一个单词,表示一组数据三张牌的最大牌型,空格后再输出此牌型的(最大)点数。
所有牌型从大到小排列如下(豹子>同花顺>顺子>同花>对子>花牌):
(1)豹子(Leopard):三张牌点数一样,如5S 5H 5C。
(2)同花顺(Flush straight):三张牌同花色且点数恰好相邻,如5S 6S 7S。
(3)顺子(Straight):三张牌点数恰好相邻,但不同花色,如10H 11D 12C。
(4)同花(Same kind):三张牌花色相同,点数不全相同,如8H 5H 11H。
(5)对子(Pair):花色不全相同,两张牌点数相同,如11H 5C 11D。
(6)花牌(General):花色不全相同,点数全不相同,如:5D 6C 8H。

输入样例:

6
8H 8D 8C
5S 7S 6S
11C 12D 10S
1C 5C 6C
10C 8D 8H
5D 6H 12C

输出样例:

Leopard 8
Flush straight 7
Straight Q
Same kind 6
Pair 8
General Q

解题思路:

  • 要想方便判断牌型,和找出最大点数,就要先对输入的数据做个处理,用字符数组接收输入数据,提取出点数和花色,
  • 各个牌型的判断写在函数,不然不得把自己写迷糊了,
  • 别忘了还有对点数超过10之后输出的处理
  • 对子输出的点数该是那个相同的点数

参考代码:

这是第一次的思路,有些杂乱,一口气写完,还是很爽的= ̄ω ̄=

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

int score(char a[], int len) {//提取出每张牌的点数
  int num = 0;
  for (int i = 0; i < len - 1; i++) {
    num = num * 10 + a[i] - '0';
  }
  return num;
}
char flow(int number) {//处理输出时点数大于10
  switch (number) {
    case 11:
      return 'J';
    case 12:
      return 'Q';
    case 13:
      return 'K';
    case 14:
      return 'A';
  }
}
int flow_color(char card_a, char card_b, char card_c) {//结合flush函数,判断牌型是否是同花顺
  return card_a == card_b && card_b == card_c;
}
int max(int a, int b) {//最大
  return a > b ? a : b;
}
int min(int a, int b) {//最小
  return a > b ? b : a;
}
int flush(int number_a, int number_b, int number_c) {//判断三张牌的点数是否相邻,也就是顺子
  int _max = max(max(number_a, number_b), number_c);
  int _min = min(min(number_a, number_b), number_c);
  if ((number_a + number_b + number_c) * 2 == (_max + _min) * (_max - _min + 1)) {
  //判断方式是一个等差数列和公式,(_max - _min + 1)也就是n,
    return _max;

  }
  return 0;
}
int pair(int number_a,int number_b,int number_c)//判断是否是对子,
{
    return number_a==number_b?number_a:number_a==number_c?number_a:number_b==number_c?number_b:0;
}
void print(int number)//最后的输出点数
{
    if(number>10)
    printf("%c",flow(number));
    else
    printf("%d",number);
}
int same_number(int number_a, int number_b, int number_c)//判断是否是豹子
{
    return number_a == number_b && number_b == number_c;
}
void cards(int number_a, int number_b, int number_c, char card_a, char card_b, char card_c) {//判断牌型,并输出结果
  int max_num=max(max(number_a,number_b),number_c);//找出最大点数
  if (same_number(number_a, number_b, number_c)) {//牌型是否为豹子
      printf("Leopard ");
      print(number_a);
      return;//直接返回
  }
  if (flush(number_a, number_b, number_c)) {//判断三张卡牌点数是否相邻
    if (flow_color(card_a, card_b, card_c)) {//判断三张牌花色是否相同,再进入该if后就是同花顺了
        printf("Flush straight ");
    }
    else//反之,就是顺子
    {
        printf("Straight ");
    }
    print(max_num);
    return;
  }
  if (flow_color(card_a, card_b, card_c))//判断三张牌花色是否相同,也就是同花
  {
      printf("Same kind ");
      print(max_num);
      return;
  }
  else
  {
      int same=pair(number_a, number_b, number_c);//返回对子的点数
      if(same)//若有则为对子
      {
          printf("Pair ");
          print(same);
      }
      else//不是的话,那就只有花牌了
      {
          printf("General ");
          print(max_num);
      }
  }

}
int main() {
  int n;
  scanf("%d", & n);
  while (n--) {
  //用a,b,c三个输出存储输入的卡牌
    char a[4] = {
      0
    }, b[4] = {
      0
    }, c[4] = {
      0
    };
    scanf("%s %s %s", a, b, c);
    int len_a = strlen(a), len_b = strlen(b), len_c = strlen(c);
    int number_a = score(a, len_a);//得出每张卡牌的点数,
    int number_b = score(b, len_b);
    int number_c = score(c, len_c);
    char card_a = a[len_a - 1];//得出每张卡牌的花色
    char card_b = b[len_b - 1];
    char card_c = c[len_c - 1];
    cards(number_a, number_b, number_c,card_a, card_b, card_c);//判断牌型并输出
    printf("\n");//最后换行
  }
  return 0;
}

一开始没有想到用结构体,用结构体总体会清晰不少,也不用在函数里传那么多参数了( •̀ ω •́ )✧

#include<stdio.h>
#include<string.h>
struct node
{
    int number[3];//三张卡牌的点数
    char card[3];//三张卡牌的花色
    int flag;//牌型序号
    int max_num;//最大点数
    int id;//最大点数在数组number的序号
    char max_card;//最大点数卡牌的花色
    int max_card_id;//卡牌的花色的优先级,这个变量不必看,这道题还用不着,下一道题要用
}poker;
int max(int a,int b)//最大
{
    return a>b?a:b;
}
int min(int a,int b)//最小
{
    return a>b?b:a;
}
int score(char a[], int len) {//卡牌点数
  int num = 0;
  for (int i = 0; i < len - 1; i++) {
    num = num * 10 + a[i] - '0';
  }
  return num;
}
void print_flower(char card)//补充要输出的花色,这个函数是下一题会用上的,
{
    switch(card)
    {
        case 'S':
        printf("Spade ");
        break;
        case 'H':
        printf("Heart ");
        break;
        case 'C':
        printf("Club ");
        break;
        case 'D':
        printf("Diamond ");
        break;
    }
}
void flow(int number) {//输出卡牌的点数
  switch (number) {
    case 11:
      printf("J");
      break;
    case 12:
      printf("Q");
      break;
    case 13:
      printf("K");
      break;
    case 14:
      printf("A");
      break;
      default:
      printf("%d",number);
      break;
  }
}
int flow_color() {//三张卡牌花色相同
  return poker.card[0] == poker.card[1] && poker.card[1] == poker.card[2];
}
int flush(int max_num) {//三张卡牌点数相邻
  int _min = min(min(poker.number[0], poker.number[1]), poker.number[2]);
  if ((poker.number[0] + poker.number[1] + poker.number[2]) * 2 == (max_num + _min) * (max_num - _min + 1)) 
  {
    return 1;

  }
  return 0;
}
int same_number()//三张卡牌点数相同
{
    return poker.number[0] == poker.number[1] && poker.number[1] == poker.number[2];
}
int pair()//一对卡牌的点数相同
{
    return poker.number[0]==poker.number[1]?1:poker.number[0]==poker.number[2]?2:poker.number[1]==poker.number[2]?1:0;
}
void poker_model()//输出牌型
{
    switch(poker.flag)
    {
        case 1:
        printf("Leopard");
        break;
        case 2:
        printf("Flush straight");
        break;
        case 3:
        printf("Straight");
        break;
        case 4:
        printf("Same kind");
        break;
        case 5:
        printf("Pair");
        break;
        case 6:
        printf("General");
        break;
    }
}

void cards()//判断牌型
{
    int max_num=poker.number[poker.id];
    poker.max_num=max_num;
    poker.max_card=poker.card[poker.id];
    if(same_number())//牌型为豹子
    {
        poker.flag=1;
        return;
    }
    if(flush(max_num))//三张牌点数相邻
    {
        if(flow_color())//牌型为同花顺
        {
            poker.flag=2;
        }
        else//牌型为顺子
        poker.flag=3;
        return;
    }
    if(flow_color())//牌型为同花
    {
        poker.flag=4;
        return;
    }
    int same=pair();
    if(same)//牌型为对子
    {
        poker.flag=5;
        poker.id=same;
        poker.max_num=poker.number[poker.id];
        return;
    }
    
    poker.flag=6;//牌型为花牌
}
void solve()
{

    char a[4] = {
      0
    }, b[4] = {
      0
    }, c[4] = {
      0
    };
    scanf("%s%s%s", a, b, c);
    int len_a = strlen(a), len_b = strlen(b), len_c = strlen(c);
    poker.number[0] = score(a, len_a);
    poker.number[1] = score(b, len_b);
    poker.number[2] = score(c, len_c);
    for(int j=0;j<3;j++)
    {
        if(poker.number[poker.id]<poker.number[j])
        poker.id=j;
        
    }
    poker.card[0] = a[len_a - 1];
    poker.card[1] = b[len_b - 1];
    poker.card[2] = c[len_c - 1];
    cards();

}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        solve();//简化main函数
        poker_model();//输出牌型
        printf(" ");//牌型和点数间有个空格
        flow(poker.max_num);//输出点数   
        printf("\n");
    }
	return 0;
}

扑克游戏2

任务描述
请完成以下任务。

输入格式:

输入的第一行,是一个整数N,表示有N局游戏(N组数据)。
接下来的N行是N组数据,代表N局。
每行有9张扑克牌数据,前3张代表“王要账(Wangyaozhang)”手中的3张牌,中间3张代表“于龙(Yulong)”手中的牌,后3张代表“赵松(Zhaosong)”同学手中的3张牌。
例如某局前3张牌为:5S 6H 12C,其中数字表示点数(2-10代表点数为2-10的牌,11、12、13、14代表J、Q、K、A),字母表示花色的第一个字符,黑桃(Spade)、红桃(Heart)、梅花(Club)、方块(Diamond)。以上3张牌实际代表的是黑桃5、红桃6、方块Q。
所有可能牌型从大到小排列如下:
(1)豹子(Leopard):三张牌点数一样,如5S 5H 5C。
(2)同花顺(Flush straight):三张牌同花色且点数恰好相邻,如5S 6S 7S。
(3)顺子(Straight):三张牌点数恰好相邻,但不同花色,如10H 11D 12C。
(4)同花(Same kind):三张牌花色相同,点数不全同,如8H 5H 11H。
(5)对子(Pair):只两张牌点数相同,如11H 5C 11D。
(6)花牌(General):花色不全相同,点数全不相同,如:5D 6C 8H。
三人玩牌大小比较规则是:
牌型大则牌大;
牌型相同,则比较代表牌型的最大点数,点数大的牌大;
牌型和点数都相同,则比较花色,花色从大到小按黑桃(Spade)、红桃(Heart)、梅花(Club)、方块(Diamond)排列。
例如:
(1)两手牌都是豹子,点数大的牌大;
(2)两手牌都是同花顺或都是顺子或都是同花或都是花牌,比较点数最大的那张牌。
(3)两手牌都是对子,比较2个对子中各自最大的牌,例如:黑桃10方块10对,红桃10梅花10对,因为黑桃大于红桃而前一个对子大。

输出格式:

一共有N组输出,每组输出格式如下:
(1)首先单独一行,输出局的序号,后加冒号。
(2)接下来的3行,每行输出三个玩家的姓名,冒号,括号,括号内是该玩家的牌型名称和代表该牌型的最大牌花色和点数,点数为2至10和J、Q、K、A。
(3)每组输出的最后一行输出“Win:”,1个空格,后加上胜出玩家名称。

输入样例:

8
8H 8D 8C 12C 12H 12S 14D 13D 12D
5S 7S 6S 14S 13D 12C 2S 3D 5H
11C 12D 10S 2H 3H 4H 14H 13D 14C
1C 5C 6C 5H 5D 6C 7D 9D 8D
10C 5D 10H 9D 8H 9C 13H 12D 10C
5D 6H 12C 14D 13C 10H 13H 12D 10C
5H 5D 6C 8D 9C 9H 14D 13S 2C
5H 5D 6C 5S 9C 5C 8D 9S 4C

输出样例:

1:
Wangyaozhang:Leopard(Heart 8)
Yulong:Leopard(Spade Q)
Zhaosong:Flush straight(Diamond A)
Win: Yulong
2:
Wangyaozhang:Flush straight(Spade 7)
Yulong:Straight(Spade A)
Zhaosong:General(Heart 5)
Win: Wangyaozhang
3:
Wangyaozhang:Straight(Diamond Q)
Yulong:Flush straight(Heart 4)
Zhaosong:Pair(Heart A)
Win: Yulong
4:
Wangyaozhang:Same kind(Club 6)
Yulong:Pair(Heart 5)
Zhaosong:Flush straight(Diamond 9)
Win: Zhaosong
5:
Wangyaozhang:Pair(Heart 10)
Yulong:Pair(Club 9)
Zhaosong:General(Heart K)
Win: Wangyaozhang
6:
Wangyaozhang:General(Club Q)
Yulong:General(Diamond A)
Zhaosong:General(Heart K)
Win: Yulong
7:
Wangyaozhang:Pair(Heart 5)
Yulong:Pair(Heart 9)
Zhaosong:General(Diamond A)
Win: Yulong
8:
Wangyaozhang:Pair(Heart 5)
Yulong:Pair(Spade 5)
Zhaosong:General(Spade 9)
Win: Yulong

解题思路:

有上面那道题垫着,这道题会轻松一些,在当初这巨长的输入格式,也是把我唬到了

  • 规矩与前面那道题一样,但是加上了要找花色,还有比较三个人谁的牌最大

参考代码:

#include<stdio.h>
#include<string.h>
int i=0;//当前遍历到了那个人
char colors[5]={"SHCD"};//花色的优先级
struct node
{
    int number[3];//三张卡牌的点数
    char card[3];//三张卡牌的花色
    int flag;//牌型序号
    int max_num;//最大卡牌点数
    int id;//最大点数在数组number的序号
    char max_card;//最大点数的卡牌的花色
    int max_card_id;//最大点数的卡牌的花色的优先级
}poker[3];//数组3个变量代表三个人
int max(int a,int b)//最大
{
    return a>b?a:b;
}
int min(int a,int b)//最小
{
    return a>b?b:a;
}
int score(char a[], int len) {//每张牌的点数
  int num = 0;
  for (int i = 0; i < len - 1; i++) {
    num = num * 10 + a[i] - '0';
  }
  return num;
}
void print_flower(char card)//输出花色
{
    switch(card)
    {
        case 'S':
        printf("Spade ");
        break;
        case 'H':
        printf("Heart ");
        break;
        case 'C':
        printf("Club ");
        break;
        case 'D':
        printf("Diamond ");
        break;
    }
}
void flow(int number) {//输出点数
  switch (number) {
    case 11:
      printf("J");
      break;
    case 12:
      printf("Q");
      break;
    case 13:
      printf("K");
      break;
    case 14:
      printf("A");
      break;
      default:
      printf("%d",number);
      break;
  }
}
int flow_color() {//判断三张卡牌花色是否相同
  return poker[i].card[0] == poker[i].card[1] && poker[i].card[1] == poker[i].card[2];
}
int flush(int max_num) {//判断三张卡牌点数是否相邻
  int _min = min(min(poker[i].number[0], poker[i].number[1]), poker[i].number[2]);
  if ((poker[i].number[0] + poker[i].number[1] + poker[i].number[2]) * 2 == (max_num + _min) * (max_num - _min + 1)) 
  {
    return 1;

  }
  return 0;
}
int same_number()//判断三张牌点数是否相同
{
    return poker[i].number[0] == poker[i].number[1] && poker[i].number[1] == poker[i].number[2];
}
int pair()//判断有两张卡牌点数相同
{
    return poker[i].number[0]==poker[i].number[1]?1:poker[i].number[0]==poker[i].number[2]?2:poker[i].number[1]==poker[i].number[2]?1:0;
}
void poker_model()//输出牌型
{
    switch(poker[i].flag)
    {
        case 1:
        printf("Leopard");
        break;
        case 2:
        printf("Flush straight");
        break;
        case 3:
        printf("Straight");
        break;
        case 4:
        printf("Same kind");
        break;
        case 5:
        printf("Pair");
        break;
        case 6:
        printf("General");
        break;
    }
}
void compare_flower(int max_num)//这个函数是用于在牌型为对子的情况下,比较得出卡牌的最大花色
{
    for(int j=0;j<4;j++)
    {
        for(int k=0;k<3;k++)
        {
            if(poker[i].number[k]==max_num)//比较方式是筛出对子那对卡牌
            if(poker[i].card[k]==colors[j])//与数组比对如相同,那么这个就是最大花色,立即跳出
            {
                poker[i].max_card=colors[j];
                return;
            }
        }
    }
}
void compare_flower_color()//这个函数是用于牌型为豹子的,比较得出卡牌的最大花色
{
    for(int j=0;j<4;j++)
    {
        for(int k=0;k<3;k++)
        {
            if(poker[i].card[k]==colors[j])
            {
                poker[i].max_card=colors[j];
                return;
            }
        }
    }
}
void compare_color_id()//得出花色的优先级用于后面比较三个人谁的卡牌大
{
    for(int j=0;j<4;j++)
    {
        if(poker[i].max_card==colors[j])
        {
            poker[i].max_card_id=j;
            return;
        }
    }
}
void cards()
{
    int max_num=poker[i].number[poker[i].id];//三张卡牌的最大点数
    poker[i].max_num=max_num;
    poker[i].max_card=poker[i].card[poker[i].id];
    if(same_number())//牌型为豹子
    {
        poker[i].flag=1;
        compare_flower_color();
        return;
    }
    if(flush(max_num))//三张牌点数相邻
    {
        if(flow_color())//牌型为顺子同花顺
        {
            poker[i].flag=2;
        }
        else//牌型为顺子
        poker[i].flag=3;
        return;
    }
    if(flow_color())//牌型为同花
    {
        poker[i].flag=4;
        return;
    }
    int same=pair();
    if(same)//牌型为对子
    {
        poker[i].flag=5;
        poker[i].id=same;
        poker[i].max_num=poker[i].number[poker[i].id];
        compare_flower(poker[i].max_num);
        return;
    }
    
    poker[i].flag=6;//牌型为花牌
}
void solve()//这个函数主要完成对输入的处理
{

    char a[4] = {
      0
    }, b[4] = {
      0
    }, c[4] = {
      0
    };
    scanf("%s%s%s", a, b, c);
    int len_a = strlen(a), len_b = strlen(b), len_c = strlen(c);
    poker[i].number[0] = score(a, len_a);
    poker[i].number[1] = score(b, len_b);
    poker[i].number[2] = score(c, len_c);
    for(int j=0;j<3;j++)//比较出最大点数的卡牌的序号,
    {
        if(poker[i].number[poker[i].id]<poker[i].number[j])
        poker[i].id=j;
        
    }
    poker[i].card[0] = a[len_a - 1];
    poker[i].card[1] = b[len_b - 1];
    poker[i].card[2] = c[len_c - 1];
    cards();

}
int compare_score(int index,int j)//比较谁的卡牌大
{
    if(poker[index].flag>poker[j].flag)//先比较牌型
    {
        index=j;
    }
    else if(poker[index].flag==poker[j].flag)
    {
        if(poker[index].max_num<poker[j].max_num)//再比较点数
        {
            index=j;
        }
        else if(poker[index].max_num==poker[j].max_num)
        {
            if(poker[index].max_card_id>poker[j].max_card_id)//再比较花色
            {
                index=j;
            }
        }
    }
    return index;
}
int main()
{
    int n;
    scanf("%d",&n);
    char d[4][20]={"Wangyaozhang","Yulong","Zhaosong"};//三个人名称
    int count=1;//当前是第几局
    while(n--)
    {
      printf("%d:\n",count++);  //输出第几局
    for(i=0;i<3;i++)//这一局中三个人的卡牌
    {
        printf("%s:",d[i]);
        solve();//整理输入
        poker_model();//输出牌型
        printf("(");
        print_flower(poker[i].max_card);//输出花色
        flow(poker[i].max_num);//输出点数
        printf(")");        
        printf("\n");
        compare_color_id(); //花色优先级
    }

    printf("Win: ");
    int index=0;
    for(int j=1;j<3;j++)
    {
        index=compare_score(index,j);//返回胜利者的序号
    }
    puts(d[index]);//输出
    }
	return 0;
}

做来了以前做不来的题,这种感觉还是很爽的

这里就不写C++版本的了,没什么区别,硬要看就直接换头文件吧

在这里插入图片描述

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值