扑克牌游戏,两人接龙(数据结构:队列、栈、双向链表)

news/2024/5/20 6:27:22 标签: 扑克牌, 数据结构, 顺序表, ,

游戏规则:

1、将一副牌中的大小王去掉,剩余的52张牌(1-13)*4,洗牌后按顺序分配给两名选手(这里用的方法是随机抽取其中的一张牌发给选手);

2、随机抽取其中一人先出牌,之后两人轮流将自己手里最前面的牌放到桌面;

3、如果放下去的牌,在桌面上已经存在,则选手将两个相同点数的牌面之间的所有牌(含相同点数的牌),收取到自己手中,并放到最后;

4、直到其中一人手中没有牌,游戏结束;手里有牌的人胜出。

 

要点:

1、两名选手,所持牌面符合“先进先出”的原则,用顺序表作为数据结构存储(本文采用的是顺序,方便摘除和增加结点)

2、桌面的牌符合”先进后出“的原则,利用数据结构存储

3、为了增加游戏的过程可读性,增加了每一轮出牌情况,及两名选手和桌面牌面的展示;

运行情况:

开始->

结束->

 

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
/*定义,每张牌*/
typedef struct Card
{
	int hcard;
	struct Card *front; 
	struct Card *back; 
} Bcard;
/*初始化选手和桌面,创建选手牌面队列头结点和桌面牌面*/ 
Bcard *initcard()
{
	Bcard *p=(Bcard *)malloc(sizeof(Bcard));
	p->front=p;
	p->back=p;
	return p;
}
/*选手取牌*/ 
pushcard(Bcard *p,int temcard)
{
	Bcard *t = (Bcard *)malloc(sizeof(Bcard));
	if(t==NULL)
	{
		printf("申请空间失败!\n"); 
	}
	//将牌发到选手手中,申请新空间结点,连接到选手队列 
	t->hcard=temcard;
	t->back=p->back;
	p->back->front=t;
	t->front=p;
	p->back=t;
}
/*选手出牌*/ 
popcard(Bcard *p)
{
	Bcard *t;
	t=p->front;//定位要出的牌
	//摘除牌所占结点 
	t->front->back=p;
	p->front=t->front;
	printf("%3d\n",t->hcard);//显示选手出的牌 
	free(t);//释放选手已经出的牌		
}
/*遇到相同点数的牌,桌面上的牌给选手,出*/ 
popsharcard(Bcard *p12,Bcard *p3card)
{
	Bcard *t;
	pushcard(p12,p3card->back->hcard);
	t=p3card->back;
	p3card->back=p3card->back->back;
	p3card->back->front=p3card;
	free(t);//释放已经被选手收取的牌所占空间		
}
/*初始发牌*/ 
void fapai(Bcard *p1card,Bcard *p2card)
{
	Bcard *p4card=initcard();//表 整副牌初始化 1-13 * 4 
	//将52张牌(不含大小王)放入临时表 
	int i,j;
	for(i=1;i<=4;i++)
	{
		for(j=1;j<=13;j++)
		{
			pushcard(p4card,j);
		}
	}
	//洗牌结束,开始给两名选手发牌 
	int select=1; //发牌标记
	srand(time(NULL)); //随机种子 
	for(i=1;i<=52;i++) 
	{
		Bcard *ptem1;
		Bcard *ptem2;
		if(1==select)//两人轮流取牌 
		{
			ptem2=p1card;
		}
		else
		{
			ptem2=p2card;
		}
		select*=-1;//转换发牌标记 
		ptem1=p4card;
		j=rand()%(53-i)+1;//在整副牌中随机抽取一张 发牌 
		while(j>0)//定位到收取的的牌 
		{
			ptem1=ptem1->back;
			j--;
		}
		pushcard(ptem2,ptem1->hcard);//发牌给选手 
		popcard(ptem1->back);	//去除已经发过的牌 	
	}
	system("cls");//清屏,之前发牌的时候每发一次都输出一次+回车,为了看起来好看 
	printf("\n发牌结束\n");	
}
/*输出选手和桌面上的牌面信息*/ 
void shuchuxuanchou(Bcard *pp)
{
	Bcard *ppt;
	ppt=pp;
	while(1)
	{
		if(ppt->front==pp)
		{
			break;
		}
		printf("%3d",ppt->front->hcard);
		ppt=ppt->front;
	}
	printf("\n");
}
/*遍历桌面牌面,查看是否存在和要出的牌点数相同的牌*/ 
int bianli(Bcard *p3,int temcard) 
{
	Bcard *pt;
	pt=p3;
	while(pt->back!=p3)
	{
		if(temcard==pt->back->hcard)
		{
			return 1;
		}		
		pt=pt->back;
	}
	return -1;	
}
/*收牌,先将自己要出的牌放在最后,再按顺序将桌面上相同点数的牌之前的牌收取到手中,放在最后*/ 
void shouqu(Bcard *ptem,Bcard *p3card)
{
	int temcard=ptem->front->hcard;
	pushcard(ptem,ptem->front->hcard);
	popcard(ptem);
	while(1)
	{
		if(temcard==p3card->back->hcard)
		{
			pushcard(ptem,p3card->back->hcard);
			popcard(p3card->back->back);
			break;
		}
		else
		{
			printf("%3d\n",p3card->back->hcard); 
			popsharcard(ptem,p3card);	
		}	
	}			
}
/*开始游戏,随机抽取先出牌的选手,展示桌面牌面,选手牌面,其中一人手里没有牌,则对方胜利*/ 
void playgame(Bcard *p1card,Bcard *p2card,Bcard *p3card)
{
	srand(time(NULL)); //随机种子 
	int select=rand()%3;//随机确定谁先出牌 0-选手 1 先出 ,1-选手 2 先出
	Bcard *ptem; 
	if(2==select)//确定谁先出牌 
	{
		ptem=p1card;
	}
	else
	{
		ptem=p2card;
	}
	int sum=0;
	while(1)
	{
		printf("\n第 %d 轮",++sum);
		printf("\n桌面牌面");
		shuchuxuanchou(p3card);
		if(p1card->front==p1card) 
		{
			printf("\n\n选手 NO.1 手中已经无牌可出\n\n"); 
			printf("恭喜 NO.2 获得胜利\n"); 
			exit(0); 
		}
		else if(p2card->front==p2card)
		{
			printf("\n\n选 NO.2 手中已经无牌可出\n\n"); 
			printf("恭喜 NO.1 获得胜利\n"); 
			exit(0); 
		}
		int result=bianli(p3card,ptem->front->hcard);//查看桌面是否有要出的牌 
		if(-1==result)//没有 则放入桌面 
		{
			pushcard(p3card,ptem->front->hcard); 
			popcard(ptem);
		}
		else//有 则收取到正在出牌的选手手里,放在最后 
		{
			printf("\n选手收牌:\n");
			shouqu(ptem,p3card); 
			printf("\n选手 NO.1 \n");
			shuchuxuanchou(p1card);
			printf("\n选手 NO.2 \n");
			shuchuxuanchou(p2card);
		}
		/*转换出牌选手*/
		if(ptem==p1card)
		{
			ptem=p2card;
		}
		else if(ptem==p2card)
		{
			ptem=p1card;
		}		
	}
}
 
/*主函数*/ 
int main()
{
	//初始化两名对手和桌面 
	Bcard *p1card=initcard();//队列 选手 1 
	Bcard *p2card=initcard();//队列 选手 2
	Bcard *p3card=initcard();//  桌面 
	//发牌 
	fapai(p1card,p2card); 
	//展示选手 手里的牌面 
	printf("\n选手 NO.1 \n");
	shuchuxuanchou(p1card);	
	printf("\n选手 NO.2 \n");
	shuchuxuanchou(p2card);
	//开始游戏 
	printf("\n选手出牌\n");
	playgame(p1card,p2card,p3card);
	//游戏结束 
	getchar();
	return 0;
}

 

 

 

 


http://www.niftyadmin.cn/n/1579936.html

相关文章

javascript/ajax/java

欢迎大家加入 web 发群 相互学习 交流一些相关技术 让大家不断茁壮起来 群号 180716246 欢迎大家的到来转载于:https://blog.51cto.com/ourfuture/903697

windows桌面Diaolog对话框程序 ComboBox 控件(添加、删除、查找)

windows桌面对话框程序 ComboBox控件的应用及基本操作 向控件内增加下拉内容&#xff08;识别要增加的内容&#xff0c;存在则提示&#xff0c;不增加&#xff0c;不存在则直接增加&#xff09; 删除选中的下拉内容&#xff08;直接删除选中的下拉项&#xff0c;显示下拉列表…

day19 - 关于进制的转换与理解补码的知识

#include <stdio.h> enum WeekDay { Sunday,Monday,Tuesday,WednesDay,Thursday,Friday,Saturday,//注意&#xff1a;; }; void show(enum WeekDay); int main(void) { enum WeekDay day ; day Monday; show(day); return 0; } void show(enum WeekDay i) {…

简单计算器(图形界面)(double型计算,四舍五入,精度可选)定时器实现

看网课的时候&#xff0c;跟着学了一下计算器&#xff0c;但是老师只讲了int型的计算&#xff0c; 于是自己研究了一下double型的&#xff0c;结果还真是遇到了不少麻烦&#xff1b; 因为我用的是VS2017 wsprintf 不支持 浮点数 找了好多网上的帖子&#xff0c;但是C语言的没…

[辅]XUL+XPCOM 开发的相关网址

2019独角兽企业重金招聘Python工程师标准>>> 注: 以下代码是为本博另一篇博文《Firefox/Jetpack扩展开发(1)-前期准备》服务的, 光看这网址是无意义的. 虽然现在不用 XULXPCOM 进行开发了, 但以前收集的 XULXPCOM 开发的相关网址也是有价值的, 以下逐个列出. (1). f…

VS 2017 C/C++ win32DiaLogApplication(windows桌面对话框程序) 模板下载

自己学习C的过程中&#xff0c;跟着视频学习&#xff0c;遇到桌面对话框程序后就有点 不知所措了&#xff0c; 因为VS2017里面并没有提供模板&#xff0c;不知道该怎么弄这个 后来 网上查看了 好多资料&#xff0c;最终也可以实现对话框 联系的目的了 但是&#xff0c;跟视频…

C++多继承时的对象内存模型(附 查看方法)

A、B 是基类&#xff0c;C 是派生类 代码如下&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; //class C同时继承了class A 和class B 构造函数C初始化只能借助构造函数A和构造函数B //命名冲突 show()函数在每个类里面都有 会在…

在云中实现可信的Luna SA解决方案

Luna SA 5.0 HSM是适合有以下需求的企业的解决方案&#xff1a;对纸张转到电子方案&#xff0c;数字签名&#xff0c;DNSSEC&#xff0c;硬件密钥存储&#xff0c;交易加速&#xff0c;证书签名&#xff0c;编码或文件签名&#xff0c;成批密钥生成&#xff0c;数据加密以及其他…