今天无聊和妹妹一起玩了一会小猫钓鱼,随后有感就写了一下简单的用c语言实现的小猫钓鱼,接下来就进入正题吧。
小猫钓鱼的过程简单来说,就是每一轮先有一个人出牌,出完牌后检查是否桌子牌面上有相同数值的牌,有则将两张相同数值的牌及其二者之间的牌全部收入囊中,无则这张牌将保留在桌面上,随后轮到另外一人出牌,检查牌面情况,操作同第一人。如此重复每轮过程直到有人没有牌了被淘汰。
分析问题,我们可以发现两个人手上的牌可以用队列来实现,先进先出,出牌即出队,收牌则入队,而桌面上的牌可以用栈来实现,先进后出。大致框架已经有了,那如何实现出牌收牌呢,我们需要一个标志来判断出的牌是否和某张桌面上的牌有相同数值,这个flag我们可以用book数组来实现,因为去掉大小王总共13张牌,那么我们将数组大小设置为14(因为没有0),开始初始化为0,每次打入一张牌就将对应数组下标设置为1,那么每次检查就可以通过数组对应下标的数值来判断了。
接下来就是代码实现。
#include <stdio.h>
#include <stdlib.h>
struct queue{
int data[100];
int head;
int tail;
};
struct stack{
int data[100];
int top;
};
int main()
{
struct queue q1,q2;
struct stack s1;
int t;
int book[14];
q1.head=q1.tail=1;
q2.head=q2.tail=1;
s1.top=0;
//每个人多少张牌
int n;
scanf("%d",&n);
// 初始化两个人手上的牌
for(int i=1;i<=n;i++){
scanf("%d",&q1.data[q1.tail]);
q1.tail++;
}
for(int i=1;i<=n;i++){
scanf("%d",&q2.data[q2.tail]);
q2.tail++;
}
for(int i=1;i<14;i++){
book[i]=0;
}
while(q1.head<q1.tail && q2.head<q2.tail)//有牌就出牌
{
//第一个人出牌
t=q1.data[q1.head];
//没有相同数值的牌
if(book[t]==0){
s1.top++;
s1.data[s1.top]=t;
q1.head++;
book[t]=1;
}
//有相同数值的牌
else{
q1.head++;
q1.data[q1.tail]=t;
q1.tail++;
while(s1.data[s1.top]!=t){
book[s1.data[s1.top]]=0;
q1.data[q1.tail]=s1.data[s1.top];
s1.top--;
q1.tail++;
}
}
//轮到第二个人出牌了
t=q2.data[q2.head];
if(book[t]==0){
s1.top++;
s1.data[s1.top]=t;
q2.head++;
book[t]=1;
}
else{
q2.head++;
q2.data[q2.tail]=t;
q2.tail++;
while(s1.data[s1.top]!=t){
book[s1.data[s1.top]]=0;
q2.data[q2.tail]=s1.data[s1.top];
s1.top--;
q2.tail++;
}
}
}
// 赢了
if(q1.head==q1.tail){
printf("q2获胜\n");
printf("q2手上的牌有\n");
for(int i=q2.head;i<q2.tail;i++){
printf("%d ",q2.data[i]);
}
printf("\n");
if(s1.top>0){
printf("桌上还有这些牌\n");
for(int i=1;i<=s1.top;i++){
printf("%d ",s1.data[i]);
}
}
else
printf("桌上没牌了");
}
if(q2.head==q2.tail){
printf("q1获胜\n");
printf("q1手上的牌有\n");
for(int i=q1.head;i<q1.tail;i++){
printf("%d ",q1.data[i]);
}
printf("\n");
if(s1.top>0){
printf("桌上还有这些牌\n");
for(int i=1;i<=s1.top;i++){
printf("%d ",s1.data[i]);
}
}
else
printf("桌上没牌了");
}
getchar();
getchar();//吃回车用的
return 0;
}