C语言每日一练
2021年12月7日

文章目录

  • 题目描述
  • 问题分析
  • 代码实现
  • 运行结果
  • 网上参考

题目描述

一副扑克有52张牌,打桥牌时应将牌分给4个人。请设计一个程序完成自动发牌的工作。要求:黑桃用S (Spaces)表示,红桃用H (Hearts)表示,方块用D (Diamonds)表示,梅花用C (Clubs)表示。

问题分析

个人思路:
这题实现起来还是比较简单的,只需定义两个多维的字符数组,第一个用来存放扑克的编号,第二个用来存放4个玩家的手牌。

52张牌发给4个人,需要发13轮,每轮按玩家的编号顺序给他们发牌,发牌时,用随机函数生成要发牌的编号(随机函数的介绍可以参考我第61天的练习),如果该牌之前没被发放(已发放的牌用'\0'标记),则将牌的编号存放到玩家的手牌数组中,同时将该牌的编号赋值为'\0'。如果生成的随机数对应的牌已经被发过了,则继续生成新的随机数。当52张牌全部发放完毕,打印发牌的结果。

扑克数组char poker[4][13];中的4表示花色种类有四种,13表示每种有13张(13个编号),扑克牌的编号(名字)用字符表示,分别为:{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'}'0'表示10)

玩家的手牌数组是一个三维字符数组,char players[PLAYER_NUMBER][4][13] = {0}; (PLAYER_NUMBER是玩家数量,4表示牌的花色种类有4种,13为某种花色的牌最多13张)
初始化时,手牌数组的所有值设置为'\0',表示手上无牌。

代码实现

#include <stdio.h>
#include <stdlib.h>       //srand()/rand()
#include <time.h>         //time()#define CARD_NUMBER   52  //总牌数(目前仅支持52)
#define PLAYER_NUMBER 4   //玩家数量/******************************************************************************* @brief 给某个玩家发牌* @param player_id  玩家编号* @param players    玩家手牌数组* @param left_num   剩余可发放牌数* @param poker      扑克牌数组* @return   返回0表示发牌成功,返回-1表示无牌可发******************************************************************************/
int Distribute_Card(int player_id, char players[][4][13], int *left_num, char poker[][13])
{if(*left_num <= 0)return -1;       //无牌可发int card_id = 0;     //扑克牌编号int card_index = 0;  //手牌数组下标do{/* 随机获取一个扑克牌的编号(0~52) */card_id = rand() % CARD_NUMBER;}while(poker[card_id / 13][card_id % 13] == '\0'); //如果该牌已经发放,继续获取编号(*left_num)--;       //剩余可发牌数减1while(players[player_id][card_id / 13][card_index] != '\0'){card_index++;    //到达该玩家的手牌数组有效值的下一个下标('\0'表示无效值)}/* 给玩家手牌数组赋值(加一张牌) */players[player_id][card_id / 13][card_index] = poker[card_id / 13][card_id % 13];/* 将该牌标记为无效牌(已发放) */poker[card_id / 13][card_id % 13] = '\0';return 0;
}/******************************************************************************* @brief 打印发牌结果* @param players    玩家手牌数组******************************************************************************/
void Print_Result(char players[][4][13])
{int i = 0, j = 0, k = 0;/* 牌的类别 */char card_name[][8] = {"黑桃", "红桃", "方块", "梅花"};for(i = 0; i < PLAYER_NUMBER; i++){printf("\n玩家%d:\n", i + 1);for(j = 0; j < 4; j++){printf("%s: ", card_name[j]); //打印卡牌类型//依次打印某玩家该类型的手牌for(k = 0; players[i][j][k]!= '\0' && k < 13; k++){if(players[i][j][k] == '0')printf("10 ");        //'0'对应10elseprintf("%c ", players[i][j][k]);}printf("\n");}}
}int main()
{/* 扑克牌数组 */char poker[4][13] = {{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'},\{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'},\{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'},\{'2', '3', '4', '5', '6', '7', '8', '9', '0', 'J', 'Q', 'K', 'A'}};int left_num = sizeof(poker);             //剩余可发放牌数(应该等于CARD_NUMBER)char players[PLAYER_NUMBER][4][13] = {0}; //玩家手牌数组int i = 0, j = 0, k = 0;//用系统秒数初始化随机数种子srand((unsigned)time(NULL));/* 给每个玩家发牌 */for(i = 0; i < CARD_NUMBER/PLAYER_NUMBER + 1; i++) //当玩家是奇数时,需要+1(这个值只能多不能少){for(j = 0; j < PLAYER_NUMBER; j++){//给某一个玩家发牌if(!Distribute_Card(j, players, &left_num, poker))k++;  //发牌成功次数+1}}printf("\n成功发牌%d次!\n", k); //总发牌次数Print_Result(players); //打印结果return 0;
}

运行结果

网上参考

原文链接:http://c.biancheng.net/cpp/html/3363.html

这份代码的实现思路和我差不多,但是还是存在许多细节上的差异,同时他还在发牌结束后给每个人的手牌进行了排序(从大到小)。【不过他的随机函数的随机数种子是固定的,这样会导致每次运行的结果都相同】

#include<stdlib.h>
#include<stdio.h>
int comp(const void *j, const void *i);
void p(int b[], char n[]);
int main(void)
{static char n[]={'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};int a[53], b1[13], b2[13], b3[13], b4[13];int b11=0, b22=0, b33=0, b44=0, t=1, m, flag, i;while( t<=52 )  /*控制发52张牌*/{m=rand()%52;  /*产生0到51之间的随机数*/for(flag=1,i=1; i<=t&&flag; i++)  /*查找新产生的随机数是否已经存在*/if(m==a[i])flag=0;  /*flag=1表示产生的是新的随机数,flag=0表示新产生的随机数已经存在*/if(flag){a[t++]=m;  /*如果产生了新的随机数,则存入数组*//*根据t的模值,判断当前的牌应存入哪个数组中*/if(t%4==0)b1[b11++]=a[t-1];elseif(t%4==1)b2[b22++]=a[t-1];elseif(t%4==2)b3[b33++]=a[t-1];elseif(t%4==3)b4[b44++]=a[t-1];}}qsort(b1, 13, sizeof(int), comp);  /*将每个人的牌进行排序*/qsort(b2, 13, sizeof(int), comp);qsort(b3, 13, sizeof(int), comp);qsort(b4, 13, sizeof(int), comp);p(b1, n);  /*分别打印每个人的牌*/p(b2, n);p(b3, n);p(b4, n);return 0;
}
void p(int b[], char n[])
{int i;printf("\n\006 ");  /*打印黑桃标记*/for(i=0; i<13; i++)  /*将数组中的值转换为相应的花色*/if(b[i]/13==0)  /*找到该花色对应的牌*/printf("%c ", n[b[i]%13]);printf("\n\003 ");  /*打印红桃标记*/for(i=0; i<13; i++)if((b[i]/13)==1)printf("%c ", n[b[i]%13]);printf("\n\004 ");  /*打印方块标记*/for(i=0; i<13; i++)if(b[i]/13==2)printf("%c ", n[b[i]%13]);printf("\n\005 ");  /*打印梅花标记*/for(i=0; i<13; i++)if(b[i]/13==3 || b[i]/13==4)printf("%c ", n[b[i]%13]);printf("\n");
}
int comp(const void *j, const void *i)  /*qsort调用的排序函数*/
{return(*(int*)i-*(int*)j);
}

C语言每日一练——第64天:自动发牌程序相关推荐

  1. C语言每日一练——第28天:要求输出国际象棋棋盘

    C语言每日一练 2021年10月6日 题目描述 要求输出国际象棋棋盘 分析 先看看国际象棋的棋盘的长相: 可以看出,国际象棋棋盘呈正方形,里面包含8x8总共64个小方格,它们黑白相间.要想在控制台输出 ...

  2. C语言每日一练——第57天:递归解决分鱼问题

    C语言每日一练 2021年11月13日 文章目录 题目描述 分析 代码实现 运行结果 网上参考 题目描述 A.B.C.D.E这5个人合伙夜间捕鱼,凌晨时都已经疲惫不堪,于是各自在河边的树丛中找地方睡着 ...

  3. 6 获取数组中最小值_C语言每日一练8——数组中最大值和最小值

    题目: 利用指针函数,求某数组中的最大值和最小值. 实现代码: /* ================================================================= ...

  4. C语言每日一练——第85天:三色球问题

    C语言每日一练 2022年3月8日 文章目录 题目描述 问题分析 代码实现 运行结果 网上参考 题目描述 一个口袋中放有12个球,已知其中3个是红的,3个是白的,6个是黑的,现从中任取8个,问共有多少 ...

  5. C语言每日一练——第73天:谁是窃贼问题

    C语言每日一练 202年1月8日 文章目录 题目描述 问题分析 代码实现 运行结果 网上参考 题目描述 警察审问4名窃贼嫌疑犯.现在已知,这4人当中仅有一名是窃贼,还知道这4个人中的每个人要么是诚实的 ...

  6. C语言每日一练——第35天:打印菱形

    C语言每日一练 2021年10月13日 题目描述 输入菱形的高度n(必须为奇数),即正中间星号的个数,打印出用星号组成的菱形 分析 要打印菱形,先要构想要打印的图形样子,就比如下图这种: 我们可以根据 ...

  7. C语言每日一练——第10天:求一个矩阵主对角线及副对角线元素之和

    C语言每日一练 2021年9月18日 题目描述 求一个矩阵主对角线及副对角线元素之和 分析 在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,矩阵是高等代数学中的常见工具,也常见于 ...

  8. C语言每日一练——第1天:字母大小写转换

    C语言每日一练 2021年9月9日 本人C语言菜鸟,最近工作中频频出现C语言小错误,遂决定使用笨方法提高我的C语言水平,坚持每天一个C语言小练习,养成C语言手感,从此让编程成为习惯. 题目描述 从键盘 ...

  9. 【C语言每日一练——第1练:字母大小写转换】

    C语言每日一练 2022年6月13日 题目描述 从键盘输入一个大写字母,要求改用小写字母输出 分析 从键盘输入可以使用scanf或getchar等函数. 大写字母是一个字符,字符类型数据在C语言中是以 ...

最新文章

  1. 【Linux】一步一步学Linux——grep命令(49)
  2. 玩转oracle 11g(3):配置监听
  3. linux c语言fifo例程,FIFO在C语言中的应用
  4. python数字转字符串_python中如何将数字转字符串
  5. 7月最强书单丨博文视点新品畅销TOP10,让技术带你燃爆整个7月
  6. 内网神器cobaltstrike使用教程
  7. 虚拟机安装CentOS6.5分配内存一般20G,之后如何扩展内存,扩充磁盘!
  8. 三星S9微信和服务器怎么连接,三星s9 微信在后台为什么收不到消息 | 手游网游页游攻略大全...
  9. 什么是盒子模型,盒子模型,标准盒模型,怪异盒模型,两种盒模型的区别,box-sizing属性
  10. [滴滴校招]末尾0的个数
  11. 中国商业环境发展的五个阶段浅析
  12. C语言中pthread或Windows API在多线程编程中的基本应用
  13. 黄章出山的730天:牢牢掌控魅族,绝不放权!
  14. java 日期相差月数_Java计算两个日期相差的月数
  15. mysql 获取倒数第二_MySQL查询倒数第二条记录实现方法
  16. java修改器为什么我打不开_烧饼修改器怎么打不开 烧饼修改器打不开解决方法...
  17. 给在校学生的科普文:数字芯片后端工程师的日常
  18. HTML期末作业-在线电影腾龙网站HTML模板(HTML+CSS+JavaScript)
  19. 文件服务器报告,如何对文件服务器进行精细化管理之三:存储报告(示例代码)...
  20. 荣誉时刻!金睛云华荣获腾讯数字安全创新大赛季军!

热门文章

  1. python中文件分类_李亚涛:python实现电脑文件一键分类
  2. 特斯拉向上,蔚来汽车向前
  3. java中事物是什么意思_java里 声明式事务是什么意思呢?
  4. vbs 杀死进程_VBS杀死指定进程
  5. 关于关闭谷歌的QUERY_ALL_PACKAGES权限问题
  6. 重启计算机请等待当前程序完成卸载,Win7卸载软件提示“请等待当前程序完成卸载或更改”三种解决方法...
  7. Swift 2.2 基础语法
  8. 软驱光碟安装linux系统,无光驱和软驱安装debian的方法
  9. imx6平台video简介(一)
  10. 【随机过程】第二章——随机过程概论