新手上路,要做一个憋七的出牌程序,如果有会的大神,求指导下
【问题描述】憋七游戏是一种简单有趣的扑克游戏,玩家人数为4人,使用一副牌,去掉大小王,共52张牌。玩家每人各发13张牌,以自己为主,不与其他玩家配合。游戏中以4个花色的7为基准接牌,无牌可接时则必须扣牌(不可再拿回手中),玩家手中牌(不算扣下的牌)全部出完则游戏结束,游戏结算以扣牌点数最少或没有扣牌的玩家获胜。有兴趣的同学可以自行上网查阅游戏规则,这里我们将其以数据结构的术语重新描述为:
1. 每种花色均为一个双端队列,且只能输入,不能输出,每个队列的第一个输入元素(牌张)必须为7;
2. 向队列中插入的元素必须与队列中两端的元素花色相同且在数值上相邻。例如,当队列中仅有黑桃7时,则只有黑桃8或黑桃6可插入黑桃队列中;若红心队列中已有6、7、8、9,则玩家手上只有红心5或者红心10可插入到红心队列中。其余依此类推;
3. 无论发牌结果如何,手中有黑桃7的玩家必须首先将黑桃7打出,置于桌面。依顺时针次序,其他玩家出掉手中的活牌并加入到桌面上的队列两端,若无活牌可出,则扣掉一张牌。出牌过程连续进行,不存在出牌权的问题;
4. 所谓活牌,是指与桌面上已有的牌花色相同且点数相邻的牌,或者一张任意花色的7;玩家手上若有活牌,则必须选择一张加入队列,不可扣牌;
5. 扣牌:玩家手中没有活牌时必须扣掉任意一张牌,且不可让其他人看到(本程序例外),扣牌在本局不可再拿回手中;有活牌时必须出活牌,不能扣牌;扣牌后,比大于7的被扣牌张点数更大,或者比小于7的被扣牌张点数更小的牌张将失去进入队列的机会,亦将被扣掉。例如,若某玩家扣掉手中的草花10,则其他玩家手中的草花J、Q和K亦失去加入队列的机会,必定在某个时刻被迫扣下;
6. 走通:有一位玩家本局游戏没有扣牌,即该玩家本局游戏手中牌全部出完后,没有扣一张牌;
7. 计算输赢以手中被扣牌张的点数为依据,这里我们不对输赢计算方法作要求,学有余力的同学可自行处理。
【基本要求】
本程序模拟憋七的发牌和出牌过程,通过随机函数将52张扑克牌分发到四方。为方便计,可分别称为东南西北方,以•的顺序,按如下方式在屏幕上的持牌区显示出来:
北:K83 972 J764 •K9A
西:J62 KJ10864 95A •8 东:10754 5 Q102 •Q6543
南:Q9A Q3A K83 •J1072
在持牌区的下方划出左右两个区域,出牌区显示出牌过程,扣牌区显示被扣掉的牌。如下图所示:
出牌区 扣牌区
K Q J 10 9 8 7 6 5 4 3 2 A
J 10 9 8 7 6 5 4 3 2 A K Q
K Q J 10 9 8 7 6 5 4 3 2 A
• 9 8 7 6 • K Q J 10 5 4 3 2 A
此处可留出26~27列用于显示所出的牌,建议牌张点数之间留出空格以使得显示美观。
此处亦可留出24~27列用于显示被扣掉的牌(7不可能被扣,如何处理空位请自行决定)。
在出牌区下方是出牌提示区,提示该轮到哪方出牌。出什么牌或扣什么牌由人工从键盘上输入,但程序应该能做到在无牌可出时显示扣牌提示,在有牌可出时只显示出牌提示,且无论哪种情况,输入错误都能检测到并要求重新输入。
当出掉或扣掉一张牌时,持牌区中的相应数字应被空格替换掉,同时出牌区或者扣牌区中应相应显示出此牌张点数。
为防止屏幕滚动,可使用光标定位函数
#include <conio.h>
void gotoxy(int x, int y)
来实现在屏幕指定位置输出(默认情况下屏幕范围为25行80列)。亦即牌局无论进行到何时,屏幕上的内容均不能滚出屏幕外,必须固定显示,因此出牌提示区需要反复覆盖提示。
本程序只要求做到如上图的显示即可,无需考虑人机对战算法。但必须实现以下要求:
(1) 显示版式按上图形式,不得使用图形模式
(2) 牌行花色中的•可由ASCII值\006 、\003、\005和\004实现,且必须按照黑桃、红心、草花、方块的顺序显示;
(3) 每一方的牌均由随机函数产生,但显示在屏幕上时,每种花色均按照从大到小(K、Q、J、10、……、3、2、A)的顺序排列;
(4) 排序方法自行确定(Qsort除外,如果一定要使用此函数,则必须能正确说明其原型所在并能解释相关问题);
【测试数据】
由程序产生。
【实现提示】
52张牌可先分花色按从小到大的顺序存入一个一维数组,另行定义一个一维结构体数组,长度52,存放随机数和其在整个数组中的排序序号,将此序号与第一个数组下标对应起来,即可得到随机发牌的效果。
【选做内容】
模拟托管过程,即由程序控制三方牌,操作者只控制一方,程序如何选择出牌和扣牌的规则自行确定。