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

游戏规则:

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;
}

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值