纸牌游戏——小猫钓鱼

  • 游戏规则
  • 将一副扑克牌平均分成两份,每人拿一份。A先拿出手中的第一张扑克牌放在桌上,然后B也拿出手中的第一张扑克牌,并放在A刚打出的扑克牌的上面。
  • 出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹的牌全部取走,并依次放在自己手中牌的末尾。当任意一人手中的牌全部出完时,游戏结束,对手获胜。
  • 假如游戏开始时,A手中有6张牌,顺序为 2 4 1 2 5 6,B手中也有6张牌,顺序为 3 1 3 5 6 4,最终谁会获胜呢?
  • 出牌就是出队
  • 赢牌就是入队
  • 每打出一张牌就相当于入栈

【1】 创建一个结构体来实现队列

struct queue
{
	int data[1000];
	int head;
	int tail;
}

head 用来存储队头,tail 用来存储队尾。
数组 data 用来存储队列中的元素,大小可以设置得更大一些,以防数组越界。


【2】创建一个结构体用来实现栈。

struct stack
{
	int data[10];
	int top;
};

top 用来存储栈顶,数组 data 用来存储栈中的元素,大小设置为10。
q1 用来模拟A手中的牌,q2用来模拟B手中的牌。

struct queue q1,q2;
struct stack s;

【3】初始化一下队列和栈

//初始化队列q1和q2为空,此时两人手中都还没有牌
q1.head=1;
q1.tail=1;
q2.head=1;
q2.tail=1;
//初始化栈s为空,最开始的时候桌上也没有牌
s.top=0; 

【4】读入A和B最初时手中的牌,分两次读入,分别插入q1,q2中

//先读入6张牌,放到 A 手上
for(i=1;i<=6;i++){
	scanf("%d",&q1.data[q1.tail]);
	//读入一个数到队尾
	q1.tail++;
	//队尾往后挪一位 
}  
//再读入6张牌,放到B手上
for(i=1;i<=6;i++){
	scanf("%d",&q2.data[q2.tail]);
	q2.tail++;
} 

【5】
A先出牌

    t=q1.data[q1.head];

判断桌上的牌与 t 有没有相同的,枚举桌上的每一张牌与 t 进行比对

flag=0;
for(i=1;i<=top;i++){
	if(t==s[i]){
		flag=1;
		break;
	}
}

如果 flag 的值为 0 就说明A没能赢得桌上的牌,将打出的牌留在桌上。

if(flag==0){
	//A 此轮没有赢牌
	q1.head++;
	//A已经打出一张牌,所以要把打出的牌出队 
	s.top++;
	s.data[s.top]=t; 
	//再把打出的牌放到桌上,即入栈 
}

如果 flag 的值为 1就表明 A 可以赢得桌上的牌,需要将赢得的牌依次放入 A 的手中。

if(flag==1){
	//A 此轮可以赢牌
	q1.head++;
	// A 已经打出一张牌,所以要把打出的牌出队
	q1.data[q1,tail]=t;
	//因为此轮可以赢牌,所以紧接着把刚才打出的牌又放到手中牌的末尾
	q1.tail++;
	while(s.data[s.top]!=t)
	//把桌上可以赢得的牌(从当前桌面最顶部的一张牌开始取,直到取到与打出的牌相同为止
	//依次放到手中牌的末尾
	{
		q1.data[q1.tail]=s.data[s.top];
		//依次放入队尾
		q1.tail++;
		s.top--;
		//栈中少了一张牌,所以栈顶要减 1 
	 } 
} 

【6】只要两个人中有一个人的牌用完了游戏就结束了。
因此,需要在模拟两人出牌代码的外面加一个while循环来判断。

while(q1.head<q1.tail && q2.head<q2.tail)
//当队列 q1和 q2都不为空的时候执行循环 

最后一步,输出谁最终赢得了游戏,以及游戏结束后获胜者手中的牌和桌上的牌。如果A获胜了那么B的手中一定是没有牌了(队列q2 为空)。

if(q2.head==q2.tail){
	printf("A win\n");
	printf("A 当前手中的牌是")for(i=q1.head;i<=q1.tail-1;i++)
	    printf(" %d",q1.data[i]);
	if(s.top>0)
	//如果桌上有牌则依次输出桌上的牌
	{
		printf("\n桌上的牌是");
		for(i=1;i<=s.top;i++)
		    printf(" %d",s.data[i]); 
	} 
	else 
	    printf("\n桌上已经没有牌了"); 
}

AC

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct queue
{
	int data[1000];
	int head;
	int tail;
};
struct stack
{
	int data[10];
	int top;
};
int main(){
	struct queue q1,q2;
	struct stack s;
	int book[10];
	int i,t;
	//初始化队列
	q1.head=1;
    q1.tail=1;
    q2.head=1;
    q2.tail=1;
	//初始化栈
	s.top=0; 
	//初始化用来标记的数组,用来标记哪些牌已经在桌上
	for(i=1;i<=9;i++)
	    book[i]=0;
	//依次向队列插入6个数
	// A 手上的6张牌
	for(i=1;i<=6;i++){
	    scanf("%d",&q1.data[q1.tail]);
	    q1.tail++;
    }  
    //B手上的6张牌
	for(i=1;i<=6;i++){
	    scanf("%d",&q2.data[q2.tail]);
	    q2.tail++;
    }
	while(q1.head<q1.tail && q2.head<q2.tail)
    //当队列 q1和 q2都不为空的时候执行循环  
    {
    	t=q1.data[q1.head];
    	// A出 一张牌
		//判断 A 当前打出的牌是否能赢牌
		if(book[t]==0)
		//表明桌上没有牌面为 t 的牌
		{
			//A 此轮没有赢牌
			q1.head++;
			//A 已经打出一张牌,所以要把打出的牌出队 
			s.top++;
			s.data[s.top]=t;
			//再把打出的牌放到桌上,即入栈
			book[t]=1;
			//标记桌上现在已经有牌面为 t 的牌 
		} 
		else
		{
			q1.head++;
			q1.data[q1.tail]=t;
			q1.tail++;
			while(s.data[s.top]!=t){
				book[s.data[s.top]]=0;
				q1.data[q1.tail]=s.data[s.top];
				q1.tail++;
				s.top--;
			}
		}
		t=q2.data[q2.head];
		if(book[t]==0){
			q2.head++;
			s.top++;
			s.data[s.top]=t;
			book[t]=1;
		}
		else{
			q2.head++;
			q2.data[q2.tail]=t;
			q2.tail++;
			while(s.data[s.top]!=t){
				book[s.data[s.top]]=0;
				q2.data[q2.tail]=s.data[s.top];
				q2.tail++;
				s.top--;
			}
		}
	}
	if(q2.head==q2.tail){
		printf("A win\n");
	printf("A 当前手中的牌是"); 
	for(i=q1.head;i<=q1.tail-1;i++)
	    printf(" %d",q1.data[i]);
	if(s.top>0)
	{
		printf("\n桌上的牌是");
		for(i=1;i<=s.top;i++)
		    printf(" %d",s.data[i]); 
	} 
	else 
	    printf("\n桌上已经没有牌了");
	}
	else{
		printf("B win\n");
		printf("B 当前手中的牌是");
		for(i=q2.head;i<=q2.tail-1;i++)
		    printf(" %d",q2.data[i]);
		if(s.top>0){
			printf("\n桌上的书是");
			for(i=1;i<=s.top;i++)
			    printf(" %d",s.data[i]);
		} 
		else
		    printf("\n桌上已经没牌了");
	}
	getchar();getchar();
	return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值