斗地主洗牌发牌报告--数据结构(C语言)
用C语言实现的一个洗牌发牌程序

用C语言实现的一个洗牌发牌程序
刘建成
【期刊名称】《电脑》
【年(卷),期】1994(000)003
【摘要】编制玩扑克牌的各种程序时,都必须首先解决洗牌和发牌的问题,本人在反复实践中用C语言较好地完成了这一要求,现提供给大家参考。
为描述一张牌定义了一个card结构: struct card {int value; int kind; int position;} 其中成员value 表示点数,取值1到13表示A,2……10,J、Q、K,kind表示花色,取值1到4表示花色中的梅花、方块、红心、黑桃,而position表示发牌后属于哪家,取值1到4表示东、南、西、北。
然后定义一个card结构数组deck[52]来描述一副牌。
【总页数】2页(P33-34)
【作者】刘建成
【作者单位】无
【正文语种】中文
【中图分类】TP317
【相关文献】
1.扑克自动发牌洗牌机 [J], 王元荪
2.通过Visual C#2005调用Cards.dll实现扑克发牌程序 [J], 吕伟臣
3.基于C语言的斗地主发牌程序的实现 [J], 钱学林
4.用C语言实现的一个BASIC解释程序 [J], 刘胜辉; 李岩
5.用C语言实现软盘加密程序及安装程序 [J], 吴景勤
因版权原因,仅展示原文概要,查看原文内容请购买。
斗地主洗牌发牌报告--数据结构(C语言)

数据结构作业报告——斗地主洗牌发牌报告摘要1.实验目的编斗地主洗发牌的程序可以让我们了解随机数的生成,全局变量和指针的用法,熟悉线性表的基本操作,以及排序的基本思路和方法。
2.实验方法本程序主要是利用全局变量来统筹整个程序,辅之的是指针变量。
总共有三个子函数,分别为洗牌子函数,排序子函数,发牌子函数。
洗牌这个子函数利用了随机数的生成,而主函数通过指针变量把生成的随机数赋值给全局变量,再通过冒泡排序法对全局变量进行排序,最后按编号换算进行输出。
3.实验结果由运行出来的结果可以看出,此洗牌发牌符合斗地主的规则,是合法的。
随机发的牌没有重复,没有遗漏,且按照斗地主的牌的大小进行排列,即从小到大分别为:3,4,5,6,7,8,9,10,J,Q,K,A,2,小鬼,大鬼。
所以此程序是正确的,成功的。
内容一.问题重述设计一个程序生成一副总共54张的牌,来给三个玩家发牌,发给每位玩家17张牌,剩下三张作为底牌。
每次发出的牌都不一样,而且按从小到大的顺序显示每个玩家拿到的牌和底牌。
二.算法描述本程序除了运用一些条件语句,判断语句之外,主要运用了两个算法,一个是随机数的生成,一个是冒泡排序法。
随机数的生成的复杂度为O(N),其中N=54,这是在运行结果最佳的状况下才会出现的,一旦生成的随机数相同的话,通过if语句会重新生成随机数,直到生成不同的随机数。
冒泡排序法的空间复杂度为O(1),时间复杂度为O(N2),本程序中的N为54,而且运行了两次冒泡排序法,分别为牌数和花色进行排序,所以空间复杂度为2×O(1),时间复杂度为2×O(542)。
三.变量说明a[17],b[17],c[17],d[3]为全局变量的数组,分别存放玩家一,二,三的牌,以及三个底牌。
四.函数与思路说明本程序总共有3个子函数,1个主函数,其中3个子函数分别为Xipai()子函数,Paxu()子函数,Fapai()子函数。
Xipai()这个子函数利用了srand(time(0)),rand()来生成随机数1到54。
斗地主洗牌发牌报告

作业报告——斗地主洗牌发牌报告姓名:班级:学号:上机时间:报告时间:摘要本程序生成总共54张牌,给三个玩家发牌,发给每位玩家共17张牌,剩下三张作底牌。
每次发出的牌均不一样,而且按大小显示每个玩家拿到的牌和底牌。
程序运用了冒泡排序,随机函数,子函数等方法,实现了斗地主的发牌,将54张牌发成4堆(三个人的手牌和底牌)。
程序主要是洗牌,排序,发牌三个子涵数,洗牌主要用的是随机函数,排序主要用的是冒泡排序法,发牌主要用的是switch 与else if 语句。
内容一、问题重述设计一个程序生成总共54张牌,给三个玩家发牌,发给每位玩家共17张牌,剩下三张作底牌。
每次发出的牌均不一样,而且按大小显示每个玩家拿到的牌和底牌。
二、算法描述用数组card[54]表示54张牌,用1至54个数字代替54张牌洗牌函数 xipai():用随机函数将1至54这54个数字进行随机排序,然后分别赋值给数组card[54]。
为了避免随机产生重复,用flag对出现的数字进行标记。
排序函数 paixu():分别对card[1]至card[17],card[18]至card[34],card[34]至card[51],card[52]至card[54]这四组进行排序,使用冒泡排序法。
冒泡排序法的空间复杂度为O(1),时间复杂度为O(N2),本程序中的N为54,而且运行了两次冒泡排序法,分别为牌数和花色进行排序,所以空间复杂度为2×O(1),时间复杂度为2×O(542)。
发牌函数 fapai():将card[1]至card[17],card[18]至card[34],card[34]至card[51],card[52]至card[54]分成四组,然后将数字与牌对应,最后输出。
三、程序执行结果1.第一次运行结果:2.第二次运行结果:3.第三次运行结果:四、结论通过运行结果可见,本程序思路基本正确,结果合理的,可以作为斗地主的洗牌发牌程序。
用C语言实现的扑克牌洗牌程序

⽤C语⾔实现的扑克牌洗牌程序⼀副牌:54张从0开始排序:0-12表⽰⿊桃 A 1,2,3,... 10,J,Q,K13-25表⽰红桃 A 1,2,3,... 10,J,Q,K26-38表⽰草花 A 1,2,3,... 10,J,Q,K39-51表⽰⽅块 A 1,2,3,... 10,J,Q,K52,53表⽰⼤⼩王#include <stdio.h>void shuffle(char *porker){/*将存放数组初始化为1-54*/for (int i = 0; i < 54; i++){porker[i] = i;}/*⽣成随机种⼦*/srand(time(NULL));/*洗牌,⽣成随机数,两两交换*/for (int i = 0; i < 54; i++){int rnd = rand() % 54;/*指定任意⼀张牌,与当前牌进⾏交换*/int temp = porker[i];porker[i] = porker[rnd];porker[rnd] = temp;}}void play(char *porker){for (int i = 0; i < 54; i++){printf("i=%2d\t", porker[i]);if ((i + 1) %3==0)printf("\n");}}void bottom(char *porker){/*定义花⾊的枚举体*/enum TYPE{⿊桃,红桃,草花,⽅块};/*定义⼏个特殊牌的枚举体*/enum VALUE{A=0,J = 11, Q, K};printf("\n=======底牌=========\n");for (int i = 51; i < 54; i++){/*⼤⼩王特殊处理*/if (porker[i] == 52) printf("⼩王");if (porker[i] == 53) printf("⼤王");else{/*0-12代表红桃的A-1-2-K*/int type = porker[i] / 13;int value = porker[i] % 13;switch (type){case⿊桃:printf("⿊桃"); break;case红桃:printf("红桃"); break;case草花:printf("草花"); break;case⽅块:printf("⽅块"); break;}switch (value){case A:printf("A"); break;case J:printf("J"); break;case Q:printf("Q"); break;case K:printf("K"); break;default:printf("%d", value); break; }printf("\t");}}}int main(){/*存放54张扑克的数组*/char porker[54] = { 0 };/*洗牌*/shuffle(porker);/*出牌*/play(porker);/*底牌,3张底牌*/bottom(porker);system("pause");return0;}。
C语言斗地主课程设计

C语言斗地主课程设计一、课程目标知识目标:1. 理解C语言的基本语法和结构,掌握数组、函数、指针等基本概念。
2. 学习并掌握C语言实现斗地主游戏的流程和关键算法。
3. 了解计算机编程解决问题的方法和逻辑思维能力。
技能目标:1. 能够运用C语言编写简单的斗地主游戏程序,实现洗牌、发牌、出牌等基本功能。
2. 培养学生的编程实践能力,提高调试和解决问题的技巧。
3. 学会使用C语言进行团队协作,完成一个小型项目。
情感态度价值观目标:1. 培养学生对计算机编程的兴趣,激发学习热情,形成主动探究的精神。
2. 培养学生的团队协作意识,学会相互尊重、沟通和合作。
3. 培养学生面对困难的勇气和毅力,培养克服挫折、持续进步的信心。
课程性质:本课程以实践为主,理论联系实际,让学生在动手实践中掌握C语言编程技能。
学生特点:学生具有一定的C语言基础,对编程感兴趣,喜欢挑战性任务。
教学要求:教师需引导学生主动参与,注重培养学生的编程思维和实际操作能力,同时关注学生的情感态度价值观的培养。
将课程目标分解为具体的学习成果,便于教学设计和评估。
二、教学内容1. C语言基础知识回顾:数组、函数、指针、结构体等。
- 教材章节:第一章至第四章- 内容:数据类型、运算符、控制结构、数组操作、函数定义与调用、指针概念、结构体与联合。
2. 斗地主游戏规则介绍与算法分析:- 教材章节:第五章算法设计与分析- 内容:游戏规则、牌型识别、牌型大小比较、出牌策略、洗牌与发牌算法。
3. C语言实现斗地主游戏:- 教材章节:第六章至第七章- 内容:编写洗牌、发牌、出牌等功能的函数,实现游戏主逻辑。
4. 游戏功能模块设计与实现:- 教材章节:第八章模块化编程- 内容:功能模块划分、模块间通信、代码重构与优化。
5. 团队协作与项目实践:- 教材章节:第九章团队协作与项目管理- 内容:项目分组、任务分配、进度控制、代码合并与调试。
教学内容安排与进度:- 第一周:回顾C语言基础知识,介绍斗地主游戏规则。
java学习案例-斗地主洗牌发牌

斗地主洗牌发牌【案例介绍】1.任务描述扑克牌游戏“斗地主”,相信许多人都会玩,本案例要求编写一个斗地主的洗牌发牌程序,要求按照斗地主的规则完成洗牌发牌的过程。
一副扑克总共有54张牌,牌面由花色和数字组成(包括J、Q、K、A字母)组成,花色有♠、♥、♦、♣ 四种,分别表示黑桃、红桃、方块、梅花,小☺、大☻分别表示小王和大王。
斗地主游戏共有3位玩家参与,首先将这54张牌的顺序打乱每人轮流摸一次牌,剩余3张留作底牌,然后在控制台打印3位玩家的牌和3张底牌。
2.运行结果任务运行结果如图6-1所示:图6-1 运行结果图【任务介绍】●学会分析“斗地主之洗牌发牌”任务的实现思路。
●根据思路独立完成“斗地主之洗牌发牌”任务的源代码编写、编译及运行。
●掌握List集合和Map集合特点及常用方法的使用。
●掌握集合遍历的方式。
【实现思路】(1)要实现纸牌程序,首先需要完成纸牌的组装。
牌面是由花色(包括♠、♥、♦、♣花色)和数字(包括J、Q、K、A字母)两部分组成,可以创建两个ArrayList集合作为花色集合与数字集合,存储时需要注意。
比10大的牌的数字用J、Q、K表示,1用A表示。
(2)将花色集合与数字集合这两个循环进行嵌套循环,将花色与数字组合,形成52章牌,并赋予其编号。
将组合后的牌存放到一个HashMap集合中,集合的Key值是编号,value值是组装完成的纸牌。
还有两张牌是大小王(小☺表示小王、大☻表示大王)。
由于组装规则不一致,需单独使用add()方法将这两张牌加入到HashMap集合中。
(3)创建一个数字集合,用这个数字集合代替纸牌完成洗牌和发牌操作。
由于纸牌的数量是54张,所以创建集合范围是0~53。
(4)可以使用Collection类的shuffle()方法完成打乱数字集合的操作,实现洗牌效果。
由于只有3个人,所以可以使用for循环,通过将数字与3取余的方法,将代表不同纸牌的数字分配给不同人与底牌,实现发牌效果。
C语言实现斗地主发牌程序
实验四、斗地主发牌程序的实现一、实验目的1.了解线性表的顺序存储与基本操作;2.了解线性表的链接存储与基本操作;二、实验工具VC6.0三、实验练习和要求3.1实验内容:1)考虑好纸牌的存储结构,定义好纸牌大小的比较规则;2)分别建立顺序线性表和链接线性表,可以进行定位删除,可以进行保序插入,可以进行顺序输出……;3)利用上述线性表类,构造若干个线性表的实例,构造一个含有全部纸牌的线性表,从中随机抽取……随机发给三家(每家17张),并保留底牌3张;4)按大小顺序分别输出各家的牌和底牌。
3.2实验要求:1)利用♣♦♥♠王显示每家发得的牌和底牌(ASCII:\5\4\3\6);2)每家的牌要求有序排列(数字中3最小,2最大,不同的花色按♣,♦,♥,♠,王渐大处理);3)所发的牌是随机的;4)顺序线性表和链接线性表都要用到。
3.3实验难点:1)如何存储一张牌;2)如何比较牌的大小(345678910JQKA2);3)如何实现顺序表与链接表的无差别性?3.4实现提示1)54张牌可以用整数:0--53来表示,也可以用两个独立的整数来表示;2)用利用C语言的RAND()函数来产生随机数;3)牌的大小比较规则,除王比较大外,一般的牌先比较点儿数,再比较花色;4)建议用保序插入,而不要使用最后排序。
3.5注意事项1)顺序表和链接表的操作接口要尽量一致;2)345678910JQKA2中的10占两位?3)大王与小王的特殊处理。
3.6本次实验可以三人构成学习小组,上交一份作业,并给出每一个人贡献分数。
四、实验内容本次实验分别使用顺序表和单链表实现,三人手中的牌都已经按照大小以及花色从小到大排序。
代码如下:➢顺序表实现随机发牌#include<stdio.h>#include<malloc.h>#include <time.h>#include <stdlib.h>#define MaxSize 100typedef int dataType;typedef struct {dataType data[MaxSize];int size ;}SqList;SqList* CreateList(dataType a[],int n){SqList*t=(SqList*)malloc(sizeof(SqList));for(int i=0;i<n;i++)t->data[i]=a[i];t->size=n;return t;}SqList* CreateListemp(){SqList *t =(SqList *)malloc(sizeof(SqList));t->size=0;return t;}void Exchange(SqList *l,int i,int j){int temp;temp=l->data[i];l->data[i]=l->data[j];l->data[j]=temp;}int Min(SqList *l){int min=l->data[0];for(int i=1;i<l->size;i++){if(l->data[i]<min) min=l->data[i];}return min;}void Delete(SqList *l,int k){if (k<1||k>l->size) exit(1);for (int i=k;i<l->size;i++)l->data[i-1] =l->data[i];l->size--;}int Locate(SqList *l,dataType x){for(int i=0;i<l->size;i++)if(l->data[i]==x) return i+1;return 0;}void Print(SqList *l){for (int i=0;i<l->size;i++)printf("%d ",l->data[i]);}SqList* Sort(SqList *pa){SqList *pb=CreateListemp();int M;for(int i=0;i<17;i++){M=Min(pa);pb->data[i]=M;Delete(pa,Locate(pa,M));pb->size++;}return pb;}int main(){int a[54],i,j,N;int one[17];int two[17];int three[17];int cover[3];char *poker[]={"梅花3","方块3","红桃3","黑桃3","梅花4","方块4","红桃4","黑桃4","梅花5","方块5","红桃5","黑桃5","梅花6","方块6","红桃6","黑桃6", "梅花7","方块7","红桃7","黑桃7","梅花8","方块8","红桃8","黑桃8","梅花9", "方块9","红桃9","黑桃9","梅花10","方块10","红桃10","黑桃10","梅花J","方块J", "红桃J","黑桃J","梅花Q","方块Q","红桃Q","黑桃Q","梅花K","方块K","红桃K", "黑桃K","梅花A","方块A","红桃A","黑桃A","梅花2","方块2","红桃2","黑桃2", "小王","大王"};printf("顺序表实现:3个人,每人随机发17张牌,留3张底牌。
数据结构__扑克牌发牌问题[1]
内容:问题重述:设计一个四个人玩的纸牌游戏的程序,一共有五十四张牌,要发给四个人,并且每次发出的牌都不一样。
并且符合纸牌的规则(可以是桥牌、升级、红四、斗地主等,但是必须说明规则)。
并且程序能按照设定的游戏规则从小到大进行排序,如果有底牌的话要说明底牌的情况。
最后要验证每次发牌是否合法。
该程序纸牌的玩法:在一副牌中,去除大小王,然后2最大其次是A,然后按顺序从大到小一次减小。
所用到的具体算法:冒泡法,线性表删除元素操作;具体做法为:先将一副扑克牌中的大小王拿掉,还会剩下52张牌,在进行随机的洗牌,将所有的排顺序打乱,然后在打乱后一定的顺序情况下,按照规则平均分发给四个人,每人会得到十三张牌,最后将每人手里的牌按照3、4、5、6、7、8、9、10、J、Q、K、A、2的顺序进行排列,在排列过程中会出现花色的前后顺序排列。
再将四个人手里的拍验证,检验是否每张牌是否都出现并且只出现一次。
如果出现并且只出现一次,说明程序成功,否则程序失败,则需要重新进行程序的检验,修改。
流程图大致情况:设计的结构体变量说明:char CardColor是存储花色的变量char CardNumber[2]是存储扑克牌的面值变量int flag;//判断标志struct pukepai Card[52]用char类型存储52张扑克牌int card[52]用int类型形式并且,我们在一开始定义每张牌的变量每张牌现在我们给予赋值,例如108代表方块8,212代表红桃Q,其中三位数中第一为代表花色:1代表方块,2代表红桃,3代表梅花,4代表黑桃。
01代表A,02代表2,依次类推,11代表J,12代表Q,13代表K。
具体的函数说明均在程序中标注,不再重复说明。
程序执行结果为:1.2.3.结论:通过以上多次程序运行,满足了多次结果不相同,并保证每次都会有所有的排出现且仅出现一次。
遇到的问题:对一些代码的含义不太清楚,用起来不太熟练。
洗牌游戏在Qt开发环境下使用C开发的纸牌洗牌小游戏
洗牌游戏在Qt开发环境下使用C开发的纸牌洗牌小游戏在现代社会中,人们对休闲娱乐的需求越来越高。
为了满足这一需求,各种各样的游戏应运而生。
纸牌游戏作为一种简单而又经典的游戏形式,深受广大玩家的喜爱。
为了提供一种便携式的纸牌游戏体验,我们可以利用Qt开发环境下的C语言来开发一个纸牌洗牌小游戏。
首先,我们需要明确游戏的设计目标。
这款小游戏的核心功能是实现一副扑克牌的洗牌操作,并在界面上展示给用户。
为了使游戏更加有趣,可以在洗牌的过程中添加动画效果,增加玩家的娱乐体验。
此外,我们还可以提供一些额外的功能,比如重新洗牌或者切换牌组。
基于Qt的应用程序开发框架,我们可以采用MVC(模型-视图-控制器)模式来设计这个小游戏。
模型负责管理扑克牌的数据结构,并提供必要的算法来执行洗牌和排序的操作。
视图则是用户界面的呈现,包括扑克牌的图形显示和交互元素等。
控制器则是连接模型和视图之间的桥梁,负责处理用户的输入操作,例如点击、拖拽等。
在模型层面,我们可以设计一个Card类来表示扑克牌。
每张牌都有一个花色和一个数字,可以采用枚举类型来表示。
我们可以使用一个数组或者链表来管理一副完整的扑克牌,并实现基本的洗牌和排序方法。
洗牌方法可以采用随机算法,通过交换两张牌的位置来打乱顺序。
排序方法可以根据花色和数字进行排序,使得牌组按照规定的顺序排列。
在视图层面,我们可以通过Qt的图形绘制功能来展示扑克牌的图像。
可以使用QGraphicsView来构建一个扑克牌的桌面,将每张牌作为一个独立的图形项添加到桌面中。
在洗牌的过程中,可以运用Qt的动画框架来实现流畅的过渡效果。
用户可以通过点击按钮或者拖拽牌组来触发洗牌操作。
最后,在控制器层面,我们可以利用Qt的信号和槽机制来处理用户的输入。
可以为按钮的点击事件和牌组的拖拽事件设置相应的槽函数,用于调用模型的洗牌和排序方法。
在洗牌过程中,可以通过连接定时器的时间信号和动画的更新槽函数,实现动画效果的连续展示。
斗地主的制作与实现课程设计报告(附完整源代码)
《游戏设计概论》课程设计报告题目斗地主的制作与实现专业班级学号姓名同组人员一、课程设计的内容、要求完成一个网络版的斗地主。
对于联网斗地主,要实现以下功能:1,能够联网对战,能及时出牌并能与主机一起更新游戏状态。
2,能正确判断胜负和游戏的开始与结束。
3,能认清地主和农民,能正确记分。
4,整个游戏界面如下图所示。
上面中间是游戏地主最后拿的三张牌,左右分别是玩家的牌,下面中间是自己的牌。
在游戏的右下方有2个按钮,分别是出牌和过牌。
5,这个游戏是用鼠标进行操作的,单击自己的牌可以把它们选中,当轮到自己出牌时,就可以单击出牌按钮,出自己已经选中的牌,或者单击过牌按钮,放弃出牌机会。
游戏开始时会有选地主的过程,可以单击出牌选择自己是地主,也可以单击过牌选择放弃,如果所有的玩家都选择放弃,则重新发牌。
二、所采用的数据结构没有.三、主要模块(或函数)及其功能本游戏的所有模块如下图所示:其中主要模块功能:Managers模块:这是本游戏的核心模块之一。
函数:void GameStart();//游戏初始化,发牌。
void SendCard(); //发牌void CardsInfo(Card ca[],int &num,int &min,int &type);//用来得到牌的信息。
到底是炸弹,连牌,还是什么的。
void PlayS(int min2,int type2,int num2);//设置与发出声音,用来通知玩家所打的牌的大小与种类。
void Updata();//根据游戏状态的改变,从而设置游戏界面的状态。
Card模块:记录了一张牌的所有信息,包括大小、类型、是否被玩家选中。
CProgramView模块:编辑游戏界面函数:void DrawCardOut(int k);void DrawLeft();//绘出剩下的地主的牌,当地主还没决定的时候画的是牌的背面,决定地主//后画出地主的牌void DrawPlayername();//根据传入的字符串,绘出玩家的名称void OnPass();//点击过牌按钮后的响应函数void OnSendCard();//画出当前玩家所出的牌int SelectNum(int num,int mx,int my);//判断玩家点牌后具体点的是哪一张void DrawOtherCard();//画出另外两个玩家还剩下的牌,以及//他们刚刚出牌void DrawMyCard();//画出当前玩家手中牌void OnCancel();//点击退出按钮后的响应函数void OnOK();//点击确定按钮后的响应函数virtual ~CProgramView();CString PlayerName[3];//用来存放三个玩家姓名的字符串void PrintAll();//整体重画CChat模块:基本对话框的聊天模块.CNet模块:网络控制CServer模块:网络主机配置NetControl模块:用于设置网络各方面的问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构作业报告——斗地主洗牌发牌报告姓名:江海强班级:070921班学号:07092007上机时间:2010-9-9报告时间:2010-9-13摘要1.实验目的编斗地主洗发牌的程序可以让我们了解随机数的生成,全局变量和指针的用法,熟悉线性表的基本操作,以及排序的基本思路和方法。
2.实验方法本程序主要是利用全局变量来统筹整个程序,辅之的是指针变量。
总共有三个子函数,分别为洗牌子函数,排序子函数,发牌子函数。
洗牌这个子函数利用了随机数的生成,而主函数通过指针变量把生成的随机数赋值给全局变量,再通过冒泡排序法对全局变量进行排序,最后按编号换算进行输出。
3.实验结果由运行出来的结果可以看出,此洗牌发牌符合斗地主的规则,是合法的。
随机发的牌没有重复,没有遗漏,且按照斗地主的牌的大小进行排列,即从小到大分别为:3,4,5,6,7,8,9,10,J,Q,K,A,2,小鬼,大鬼。
所以此程序是正确的,成功的。
内容一.问题重述设计一个程序生成一副总共54张的牌,来给三个玩家发牌,发给每位玩家17张牌,剩下三张作为底牌。
每次发出的牌都不一样,而且按从小到大的顺序显示每个玩家拿到的牌和底牌。
二.算法描述本程序除了运用一些条件语句,判断语句之外,主要运用了两个算法,一个是随机数的生成,一个是冒泡排序法。
随机数的生成的复杂度为O(N),其中N=54,这是在运行结果最佳的状况下才会出现的,一旦生成的随机数相同的话,通过if语句会重新生成随机数,直到生成不同的随机数。
冒泡排序法的空间复杂度为O(1),时间复杂度为O(N2),本程序中的N为54,而且运行了两次冒泡排序法,分别为牌数和花色进行排序,所以空间复杂度为2×O(1),时间复杂度为2×O(542)。
三.变量说明a[17],b[17],c[17],d[3]为全局变量的数组,分别存放玩家一,二,三的牌,以及三个底牌。
四.函数与思路说明本程序总共有3个子函数,1个主函数,其中3个子函数分别为Xipai()子函数,Paxu()子函数,Fapai()子函数。
Xipai()这个子函数利用了srand(time(0)),rand()来生成随机数1到54。
当然,为了使生成的数都不一样,还使用if的判断语句。
主函数把洗牌得到的54位随机数分成四组数组赋值到全局变量a[17],b[17],c[17],d[17]当中去,然后通过Paxu(),Fapai()这两个子函数来进行排序输出。
数组中的数为1到54的随机排列,而Paxu()子函数首先把1到52的数对应化成1到13的数,即是1到13对应化成1到13;14到26对应化成1到13;如此类推……而53,54就对应化成16,17。
然后把已经化成1,2的数再对应化成14,15的数,其化法如下:3 → 3 → 3;26 → 13 → 13;14 → 1 → 14;28 →2→ 15;53 → 16……然后用冒泡排序法对变化后的3到17的数进行从小到大的排序,而最初的全局变量的数组也跟着排序,最后也是用冒泡排序法对相同牌数的花色进行从小到大的排序,即方块,梅花,红桃,黑桃。
Fapai()这个子函数就是把排号序的数进行换算输出。
其换算输出如下:五.程序执行结果1.第一次运行结果:第一位的牌是:梅花3 红桃3 方块4 黑桃4 方块5 红桃5 黑桃5 方块7 红桃7 黑桃7 红桃10 方块J 梅花Q 梅花K 黑桃K 方块2 黑桃2第二位的牌是:方块3 梅花4 红桃4 方块6 黑桃6 梅花8 红桃9 黑桃9 方块10 黑桃10 红桃J 黑桃J 方块K 方块A 黑桃A 红桃2 小鬼第三位的牌是:黑桃3 梅花6 红桃6 梅花7 方块8 黑桃8 梅花9 梅花10 梅花J 方块Q 红桃Q 黑桃Q 红桃K 梅花A 红桃A 梅花2 大鬼底牌是:梅花5 红桃8 方块92.第二次运行结果:第一位的牌是:红桃3 方块4 梅花5 红桃5 方块6 梅花6 方块7 红桃7 红桃10 梅花J 红桃J 黑桃J 梅花Q 红桃K 方块A 红桃A 梅花2第二位的牌是:方块3 红桃4 黑桃4 黑桃6 梅花7 红桃8 方块9 梅花9 红桃9 黑桃9 方块10 梅花10 方块J 红桃Q 黑桃A 红桃2 大鬼第三位的牌是:黑桃3 梅花4 方块5 黑桃5 红桃6 黑桃7 方块8 梅花8 黑桃10 方块Q 黑桃Q 方块K 梅花K 黑桃K 梅花A 方块2 黑桃2底牌是:梅花3 黑桃8 小鬼3.第三次运行结果:第一位的牌是:梅花3 红桃3 黑桃4 红桃5 梅花6 梅花7 红桃7 黑桃7 梅花8 红桃8 红桃10 方块J 黑桃J 梅花K 梅花A 梅花2 大鬼第二位的牌是:方块3 方块4 方块5 梅花5 黑桃5 黑桃6 方块7 方块8 方块9 黑桃10 红桃J 方块Q 红桃Q 黑桃Q 方块A 红桃A 方块2第三位的牌是:黑桃3 梅花4 方块6 红桃6 黑桃8 梅花9 黑桃9 方块10 梅花J 梅花Q 方块K 红桃K 黑桃K 黑桃A 红桃2 黑桃2 小鬼底牌是:红桃4 红桃9 梅花10六.结论由前面的分析得知,虽然此程序的复杂度比较大,可是其基本思路是正确的,运行结果也是合法的,故本程序可以作为斗地主的洗牌发牌程序。
七.编程中遇到的问题以及解决方法在编程过程中,因为对指针的运用不是很熟练,所以导致运行多次都得不出正确结果,后来在指针的基础上加上全局变量,才把这个问题解决。
刚刚开始我是想用归并排序法对每位玩家的牌进行排序的,但是运行过程中叶遇上了一些小麻烦,后来改用冒泡排序法就轻易解决这个问题了。
八.附录#include<stdio.h>#include<time.h>#include<stdlib.h>void Xipai();void Paixu();void Fapai();int a[17],b[17],c[17],d[3];int *p ,q;void Xipai(){int m[54],n[54],r[54],i,j=0,k;srand((unsigned)time(NULL));for(i=0;i<54;i++)m[i]=i+1;for(i=0;i<54;){k=rand()%54;if(m[k]!=0){n[i]=m[k];r[j++]=n[i];m[k]=0;++i;}}p=&r[0];}void Paixu(int t[]){int pai[17],i,j=0,s,p;for(i=0;i<17;i++)if(t[i]==0) break;for(i=0;i<17&&t[i]!=0;i++){if(t[i]<14) pai[i]=t[i];else if(t[i]<27) pai[i]=t[i]-13;else if(t[i]<40) pai[i]=t[i]-26;else if(t[i]<53) pai[i]=t[i]-39;if(t[i]==53) pai[i]=16;if(t[i]==54) pai[i]=17;if(pai[i]==1) pai[i]=14;if(pai[i]==2) pai[i]=15;}for(i=0;i<16&&t[i]!=0;i++)for(j=i+1;j<17&&t[j]!=0;j++){if(pai[i]>pai[j]){p=pai[i];pai[i]=pai[j];pai[j]=p;s=t[i];t[i]=t[j];t[j]=s;}if(pai[i]==pai[j]&&t[i]>t[j]){p=pai[i];pai[i]=pai[j];pai[j]=p;s=t[i];t[i]=t[j];t[j]=s;}}}void Fapai(int t[]){int i;for(i=0;i<17;i++)if(t[i]==0) break;for(i=0;i<17&&t[i]!=0;i++)switch((t[i]-1)/13){case 0:{printf("方块");if(t[i]==1) printf("A\t");else if(t[i]==11) printf("J\t");else if(t[i]==12) printf("Q\t");else if(t[i]==13) printf("K\t");else printf("%d\t",t[i]);break;}case 1:{printf("梅花");if(t[i]-13==1) printf("A\t");else if(t[i]-13==11) printf("J\t");else if(t[i]-13==12) printf("Q\t");else if(t[i]-13==13) printf("K\t");else printf("%d\t",t[i]-13);break;}case 2:{printf("红桃");if(t[i]-26==1) printf("A\t");else if(t[i]-26==11) printf("J\t");else if(t[i]-26==12) printf("Q\t");else if(t[i]-26==13) printf("K\t");else printf("%d\t",t[i]-26);break;}case 3:{printf("黑桃");if(t[i]-39==1) printf("A\t");else if(t[i]-39==11) printf("J\t");else if(t[i]-39==12) printf("Q\t");else if(t[i]-39==13) printf("K\t");else printf("%d\t",t[i]-39);break;}case 4:{if(t[i]%13==1) printf("小鬼\t");else printf("大鬼\t");break;} }}void main(){int i;p=&q;Xipai();for(i=0;i<54;i++){if(i<17) a[i]=*(p++);else if(i<34) b[i-17]=*(p++);else if(i<51) c[i-34]=*(p++);else d[i-51]=*(p++); }printf("第一位的牌是:\n");Paixu(a);Fapai(a);printf("\n\n第二位的牌是:\n");Paixu(b);Fapai(b);printf("\n\n第三位的牌是:\n");Paixu(c);Fapai(c);printf("\n\n底牌是:\n");Paixu(d);Fapai(d);}。