第1关:纸牌游戏-钓鱼
任务描述
本关任务:给定任意6张牌给甲、乙,设计一个程序判定“纸牌游戏-钓鱼”的胜者。
相关知识
游戏规则:将一副扑克牌去掉花牌和10,只留下1~9的,即扑克牌只有0-9之间的数字,平均分成二份,每人拿一份,不妨设为甲、乙二人,甲先拿出手中的第一张扑克牌放在桌上,然后乙也拿出手中的第一张扑克牌,并放在刚打出的扑克牌的上面。出牌时,如果谁打出的牌与桌上某张牌面相同,可将二张牌及中间所夹的牌全部取走,并依次放到手中牌的末尾,然后继续出牌,直到打出的牌与桌上的牌都不相同,就这样两人交替出牌。当一人手中没牌可出时,游戏结束,对手获胜。
先来分析游戏中的几种操作,分别是出牌和赢牌,每个人的手牌可以设置成队列结构,这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。桌子可设置成一个栈的结构,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上拿走,这就相当于出栈。如果某人打出的牌与桌子上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走,即全部出栈,并且加入此人的队列。当一个人手中的牌先出完时,游戏结束,对方获胜。
本实训任务使用顺序栈和循环队列,顺序栈的头文件为sqstack.h,实现文件为sqstack.cpp,顺序队列的头文件为sqqueue.h,实现文件为sqqueue.cpp。
根据游戏的规则,定义二个队列,一个栈,二个队列交替出队,一个队列出队时,首先要在栈中查找是否有元素和此队列出队的元素相同,在顺序栈中查找是否有某张牌时,可以参考 顺序表按照值查找序号操作算法
当一个队列出队时,若出队的元素和栈中的某个元素k相同,则赢牌,出队的元素进入自己的队列,再将栈中的元素挨个出栈直到k,每出栈一个,就插入赢牌队列,赢牌队列在将栈中牌拿完以后,必须继续出牌,当栈中没有与出队元素相同的牌时,轮到另一个队列出牌。当某队列为空时,游戏结束,非空队列代表者获胜。
int LocateElem_Sq(SqStack L, SElemType e, int (*compare)(SElemType, SElemType))
{
// 在顺序栈L中查找第1个值与e满足compare()的元素的位序。
// 若找到,则返回其在L中的位序,否则返回0。
int i;
SElemType *p;
i = 0; // i的初值为第1个元素的位序
p = L.base; // p的初值为第1个元素的存储位置
int length = L.top-L.base;
while (i <length && !(*compare)(*p++, e))
++i;
if (i < length)
return i;
else
return -1;
}
编程要求
根据提示,在右侧编辑器补充代码,要注意的是出牌时,如果谁打出的牌与桌上某张牌面相同,将二张牌及中间所夹的牌全部取走后,应该继续出牌,直到打出的牌与桌上的牌都不相同。
测试说明
平台会对你编写的代码进行测试:
测试输入:
2 4 1 2 5 6
3 1 3 5 6 4
预期输出:
甲:4,1,2,5,6,
乙:1,3,5,6,4,
栈:2,3,
甲:1,2,5,6,
乙:3,5,6,4,
栈:2,3,4,1,
甲:6,1,1,2,4,3,2,
乙:5,6,4,
栈:5,3,
甲:1,2,4,3,2,
乙:4,5,6,3,5,
栈:6,1,
甲:2,4,3,2,1,4,1,
乙:5,6,3,5,
栈:6,
甲:4,3,2,1,4,1,
乙:6,3,5,
栈:6,2,5,
甲:2,1,4,1,3,3,
乙:5,6,4,5,2,6,
栈:
甲:1,4,1,3,3,
乙:6,4,5,2,6,
栈:2,5,
甲:4,1,3,3,
乙:4,5,2,6,
栈:2,5,1,6,
甲:3,3,
乙:4,4,5,6,1,5,2,2,
栈:6,1,
甲:3,
乙:4,5,6,1,5,2,2,
栈:6,1,4,3,
甲:
乙:6,1,5,2,2,4,3,4,
栈:6,1,5,3,
甲:
乙:6,1,5,2,2,4,3,4,
栈:6,1,5,3,
乙获胜
输入说明 第一行输入甲手中的6张牌; 第二行输入乙手中的6张牌。
输出说明 甲先出牌,如果发现桌面上有跟刚才打出的牌的数字相同的牌,则把从相同的那张牌开始的全部牌按次序放在自己手里的牌的末尾,再继续出牌,当桌面上没有跟刚才打出的牌的数字相同的牌时,分三行输出甲手里的牌,乙手里的牌,桌上的牌;同理,轮到乙出牌后,分三行输出甲手里的牌,乙手里的牌,桌上的牌,直到有一方获胜。
开始你的任务吧,祝你成功!
上答案:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
typedef int SElemType;
typedef int QElemType;
# include "sqstack.h"
# include "sqqueue.h"
void output(QElemType s);
void input(QElemType &s);
void outputS(SElemType s);
void inputS(SElemType &s);
int comp(SElemType a, SElemType b);
int LocateElem_Sq(SqStack L, SElemType e, int (*compare)(SElemType, SElemType)) ;
int main()
{
SqQueue q1,q2; //定义二个队列,代表甲、乙手中的牌
SqStack s; //定义一个栈,代表桌面上的牌
int i,t,x,n;
InitQueue(q1);
InitQueue(q2);
InitStack(s);
for(i=1;i<=6;i++)
{
scanf("%d",&t);
EnQueue(q1,t);
}
for(i=1;i<=6;i++)
{
scanf("%d",&t);
EnQueue(q2,t);
}
// 请在这里补充代码,完成本关任务
/********** Begin **********/
int a,b,c;
int t1,t2,*j;
while(!QueueEmpty(q1)&&!QueueEmpty(q2)){
DeQueue(q1,b);
t1=LocateElem_Sq(s,b,comp);
Push(s,b);
while(t1>=0){
j=s.base+t1;
while(j<s.top){
Pop(s,a);
EnQueue(q1,a);
}
DeQueue(q1,b);
t1=LocateElem_Sq(s,b,comp);
Push(s,b);
}printf("甲:");
QueueTraverse(q1,outputS);
DeQueue(q2,c);
t2=LocateElem_Sq(s,c,comp);
Push(s,c);
while(t2>=0){
j=s.base+t2;
while(j<s.top){
Pop(s,a);
EnQueue(q2,a);
}DeQueue(q2,c);
t2=LocateElem_Sq(s,c,comp);
Push(s,c);
}printf("乙:");
QueueTraverse(q2,outputS);
printf("栈:");
StackTraverse(s,outputS);
}
if(QueueEmpty(q1)){
printf("乙获胜");
}
/********** End **********/
return 0;
}
int LocateElem_Sq(SqStack L, SElemType e, int (*compare)(SElemType, SElemType))
{
// 在顺序栈L中查找第1个值与e满足compare()的元素的位序。
// 若找到,则返回其在L中的位序,否则返回0。
int i;
SElemType *p;
i = 0; // i的初值为第1个元素的位序
p = L.base; // p的初值为第1个元素的存储位置
int length = L.top-L.base;
while (i <length && !(*compare)(*p++, e))
++i;
if (i < length)
return i;
else
return -1;
} // LocateElem_Sq
void output(QElemType s)
{
printf("%d,",s);
}
void input(QElemType &s)
{
scanf("%d",&s);
}
void outputS(SElemType s)
{
printf("%d,",s);
}
void inputS(SElemType &s)
{
scanf("%d",&s);
}
int comp(SElemType a, SElemType b)
{
if(a>b)
return 0;
else
if(a == b)
return 1;
else
return 0;
}