前言:停了一段时间,发现自己重新开始《坦克大作战》系列项目的编写有点困难,所以决定从别的项目找找“乐子”。
大家小时候应该都玩过这样一个纸牌类游戏吧,规则是这样的:游戏开始时,双方持有数量相同的扑克牌。猜拳决定哪一方先出牌,先手方打出一张扑克牌放在桌子上;后手也打出一张扑克牌放在第一张牌的上面。此时,如果后手方打出的扑克牌与先手方的数字相同,则后手方赢牌,将桌面上两张数字相同及其中间的扑克牌依次放回到自己手中牌的末尾。游戏照此进行下去,直到一方手中没有扑克牌。
怎么样,有没有勾起童年的回忆呢?好了,不碎碎念了,先来看一看程序的运行的效果吧(程序的直观性还相当差,界面也很不友好,后期考虑编一个图形化的程序)。分享这个程序,主要是觉得它的内部逻辑值得借鉴。
程序代码如下:
#includeiostream
usingnamespacestd;
//定义队列,用于记录玩家手中的扑克牌
structqueue
{
intData[];//容量与队列的移动距离有关
intHead;//队首
intTail;//队尾
};
//定义栈,用于记录桌面上的扑克牌
structstack
{
intData[14];//根据游戏规则,桌面上最多有13张都不相同的牌
intTop;//栈顶
};
intmain()
{
//程序说明
cout"=================================================="endl;
cout"欢迎来到简易版的《小猫钓鱼》扑克牌游戏"endl;
cout"作者:王常幸"endl;
cout"=================================================="endl;
//申明队列对象,表示玩家一,玩家二
structqueueq1,q2;
//队列初始化
q1.Head=q1.Tail=0;
q2.Head=q2.Tail=0;
//申明栈对象
structstacks;
//栈初始化
s.Top=0;
//定义一个标记数组,用于标记桌面上的扑克牌
intbook[14];//没有0号牌,因此需要多申请一位
//数组初始化
for(inti=1;i14;i++)
{
book=0;
}
//定义一个中间变量,用于判断是否赢牌
intt;
//定义玩家手中初始的扑克牌数
intn;
cout"请确定玩家手中初始的扑克牌数n=";
cinn;
cout"请为玩家一发牌(1-13):"endl;
for(inti=0;in;i++)
{
cinq1.Data[q1.Tail];
q1.Tail++;
}
cout"请为玩家二发牌(1-13):"endl;
for(inti=0;in;i++)
{
cinq2.Data[q2.Tail];
q2.Tail++;
}
while(q1.Headq1.Tailq2.Headq2.Tail)//当两位玩家的手中都有牌时,游戏继续
{
//玩家一出牌
t=q1.Data[q1.Head];
q1.Head++;//打出一张牌,队首移位
//判断是否赢牌
if(book[t]==0)//没有赢牌
{
s.Top++;
s.Data[s.Top]=t;
book[t]=1;//标记打出的这张牌
}
else//赢牌
{
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--;
}
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];
q2.Head++;//打出一张牌,队首移位
//判断是否赢牌
if(book[t]==0)//没有赢牌
{
s.Top++;
s.Data[s.Top]=t;
book[t]=1;//标记打出的这张牌
}
else//赢牌
{
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(q1.Head==q1.Tail)
{
cout"玩家二Win"endl;
cout"玩家二手上的牌有:";
while(q2.Headq2.Tail)
{
coutq2.Data[q2.Head]"";
q2.Head++;
}
cout""endl;//换行
if(s.Top0)
{
cout"桌面上的牌有:";
for(inti=1;i=s.Top;i++)
{
couts.Data"";
}
}
else
cout"桌面上没有牌了!"endl;
cout""endl;
}
else
{
cout"玩家一Win"endl;
cout"玩家一手上的牌有:";
while(q1.Headq1.Tail)
{
coutq1.Data[q1.Head]"";
q1.Head++;
}
cout""endl;
if(s.Top0)
{
cout"桌面上的牌有:"endl;
for(inti=1;i=s.Top;i++)
{
couts.Data"";
}
}
else
cout"桌面上没有牌了!"endl;
cout""endl;
}
system("pause");
return1;
}
程序可以分为三部分来看:
1、定义队列,栈,数组等数据结构记录双方玩家手中的扑克牌,桌面上的扑克牌以及判断扑克牌是否相同的标记(这个是该程序逻辑的关键,队列,栈加上while循环太棒了。词穷了)
2、双方出牌规则,主要就是通过book数组判断桌面上有无相同的牌,然后根据判断结果处理玩家和桌面上的扑克牌(形象地说明下book数组的实现原理,想象一下你面前有十三个依次编号1、2、...13的木桶。相应数字的扑克牌出现在桌面上就在木桶上做上标记,画个小猫,小狗都可以;从桌面上拿走扑克牌就在相应的木桶上擦除之前的标记。严格执行这个规则,就可以很容易地实现是否赢牌的判断了)
3、根据玩家手中的扑克牌数目,判断游戏的赢家,并输出赢家手中的扑克牌和桌面上的扑克牌。
结束:这个程序还有点bug,感兴趣的小伙伴可以自己测试一下,发现什么问题欢迎留言哈。好长时间不写,文字好像不如之前的那么幽默了。嗯,得多看看脱口秀熏陶一下了。
识别上面的