纸牌游戏——小猫钓鱼
一、游戏规则
将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人手中的牌全部出完时,游戏结束,对手获胜。(小哼和小哈手中牌的牌面只有1~9)
二、题目分析
- 小哼和小哈有两种操作,分别是出牌和赢牌,这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。
- 桌子就是一个栈,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上拿走,这就相当于出栈。
- 枚举桌上的每一张牌,如果某人打出的牌与桌子上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。
- 综上所述,我们需要两个队列、一个栈来模拟整个游戏。
1,首先我们来创建一个结构体用来实现队列:
struct queue{ int data[1000]; //数组data用来存储队列中的元素 int head; //head用来存储队头 int tail; //tail用来存储队尾 };
2,再创建一个结构体用来实现栈:
struct stack{ int data[10]; //数组data用来存储栈中的元素 int top; //top用来存储栈顶 };
3,定义两个队列变量q1和q2:
struct queue q1,q2; //q1用来模拟小哼手中的牌,q2用来模拟小哈手中的牌 struct stack s; //栈变量s用来模拟桌上的牌
4,初始化队列和栈:
/*初始化队列q1和q2为空,因为此时两人手中都还没有牌*/ q1.head=1;q1.tail=1; q2.head=1;q2.tail=1; s.top=0; //初始化栈s为空,因为最开始的时候桌上也没有牌
5,读入小哼和小哈最初时手中的牌,分两次读入,每次读入6个数,分别插入q1和q2中:
for(i=1;i<=6;i++){ //先读入6张牌,放到小哼手上 scanf("%d",&q1.data[q1.tail]); //读入一个数到队尾 q1.tail++; //队尾往后挪一位 } for(i=1;i<=6;i++){ //再读入6张牌,放到小哈手上 scanf("%d",&q2.data[q2.tail]); q2.tail++; }
6,游戏开始,小哼先出牌:
t=q1.data[q1.head]; //小哼先亮出一张牌
7,枚举桌上的每一张牌与t比较(判断桌上的牌与t有没有相同的):
if(flag==0) { q1.head++; //小哼已经打出一张牌,所以要把打出的牌出队 s.top++; s.data[s.top]=t; //再把打出的牌放到桌上,即入栈 }
8,如果flag的值为1就标明小哼可以赢得桌上的牌,所以需要将赢得的牌依次放入小哼的手中:
if(flag==1) //小哼此轮可以赢牌 { q1.head++; //小哼已经打出一张牌,所以要把打出的牌出队 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 } }
9,至此,小哼出牌的所有阶段就模拟完了(小哈类似)。接下来我们要判断游戏如何结束:即只要两人中有一个人的牌用完了游戏就结束。因此我们需要在模拟两人出牌代码的外面加一个while循环来判断:
while(q1.head<q1.tail && q2.head<q2.tail){ //当队列不为空的时候执行循环
10,输出谁最终赢得了游戏,以及游戏结束后获胜者手中的牌和桌上的牌。(以小哼为例)
if(q2.head==q2.tail)//如果小哼获胜那么小哈手中一定没有牌了(队列q2为空) { printf("小哼win\n"); printf("小哼当前手中的牌是"); 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桌上已经没有牌了"); }
三、完整代码如下
#include<stdio.h> struct queue{ int data[1000]; //数组data用来存储队列中的元素 int head; //head用来存储队头 int tail; //tail用来存储队尾 }; struct stack{ int data[10]; //数组data用来存储栈中的元素 int top; //top用来存储栈顶 }; int main() { struct queue q1,q2; //q1用来模拟小哼手中的牌,q2用来模拟小哈手中的牌 struct stack s; //栈变量s用来模拟桌上的牌 int book[10]; int i,t; /*初始化队列q1和q2为空,因为此时两人手中都还没有牌*/ q1.head=1;q1.tail=1; q2.head=1;q2.tail=1; s.top=0; //初始化栈s为空,因为最开始的时候桌上也没有牌 for(i=1;i<=9;i++) book[i]=0; for(i=1;i<=6;i++){ //先读入6张牌,放到小哼手上 scanf("%d",&q1.data[q1.tail]); //读入一个数到队尾 q1.tail++; //队尾往后挪一位 } for(i=1;i<=6;i++){ //再读入6张牌,放到小哈手上 scanf("%d",&q2.data[q2.tail]); q2.tail++; } while(q1.head<q1.tail && q2.head<q2.tail){ //当队列不为空的时候执行循环 t=q1.data[q1.head]; //小哼先亮出一张牌 if(book[t]==0) { q1.head++; //小哼已经打出一张牌,所以要把打出的牌出队 s.top++; s.data[s.top]=t; //再把打出的牌放到桌上,即入栈 book[t]=1; } 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--; //栈中少了一张牌,所以栈顶要减1 } book[s.data[s.top]]=0; q1.data[q1.tail]=s.data[s.top]; q1.tail++; s.top--; } if(q1.head==q1.tail) break; 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--; } book[s.data[s.top]]=0; q2.data[q2.tail]=s.data[s.top]; q2.tail++; s.top--; } } if(q2.head==q2.tail)//如果小哼获胜那么小哈手中一定没有牌了(队列q2为空) { printf("小哼win\n"); printf("小哼当前手中的牌是"); 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("小哈win\n"); printf("小哈当前手中的牌是"); 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桌上已经没有牌了"); } return 0; }
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子里和园子外的大大们指正错误,共同进步。或者直接私信我 (^∀^)
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
您的资助是我最大的动力!
金额随意,欢迎来赏!
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
本博客的所有打赏均将用于博主女朋友的化妆品购买以及养肥计划O(∩_∩)O。我是【~不会飞的章鱼~】!