您的位置:首页 > 其它

家乡的一种棋牌游戏

2012-05-07 01:33 176 查看
进来无事,想起了家乡的一种棋牌游戏,只记得小时候玩觉得蛮有趣,呵呵,现在想起就有一种用程序实现它的冲动,

呵呵,有想法就行动了,鉴于此款游戏由多人组合才能进行,所以还是选择C/S结构开发,考虑服务器端会完成多位用

户请求,采用完成端口模型处理服务器端口连接。不多说,首先看游戏玩法规则,如下

1.游戏以 4,5,6,7,8,9,10,J,Q,K,A,2,3,大小王 的顺序分大小,4最小,王最大

2.游戏一开始必须以方块4所得者出牌,且第一次出牌必须打出方块4(可以打出多张4,但方块4必须出)

3.游戏中要是出多张牌的话,只能出同一牌值的牌(如,可以出三个5,但不能出三个5带一张或者一对)

4.要吃上家牌的话,必须要牌值大于上家的,且花色要一样(如果上家除了一个 红心4与梅花4一起,那么必须要大于牌

值的 红心与梅花 例红心5 梅花5 ,或者同牌值的大牌吃,如 黑桃 4与 方块4可以出 花色按 黑桃 红心 梅花 方块

顺序分大小,黑桃最大, 如黑桃4可以吃梅花4)

5.所有出牌都要大于上家牌(除第一次出牌以外),王可以吃任何牌,不需要判断花色,但是出牌的数量要一致,如上家是

出两个 4,那么要用王吃的话也必须出两个王,简单的说就是一个王只能吃一张牌,且大王能吃小王

好了,暂时就想到这么多了,规则大概就这些,开始吧。

关于网络间的通讯采用的是TCP/IP连接,各消息间的传递我采用了枚举来区别,及数据头就是要传达的消息类型,如下枚举

enum msgType{

WS_LOG = 1 , // 登陆

WS_SIT = 2 , // 请求坐下

WS_PLVIEW = 3 , // 用户列表

WS_COMEIN = 4 , // 进入房间

WS_RELLY = 5 , // 准备

WS_OUTROOM = 6 , //离开房间

WS_GAMESTAR = 7 , //开始游戏

WS_GAMECARD = 8 , // 发牌

WS_OUTCARD = 9 , // 出牌

WS_PASSCARD = 10 // 不出

};

程序使用VC6.0开发,服务器端为 win32控制台应用程序(由于没那么多时间去编辑用户窗口,且考虑到控制台程序为效率

最高程序,所以就用它来吧),客户端为win32应用程序,整个游戏过程为几张图片实现,为实现每张牌的显示及大小的判

断,需要专门做一个类,为此我做了如下这么一个类,它可办忙实现了好多功能,呵呵,体积虽然小,但还是有用滴,整

个游戏的关键也还是在牌这个类,其他的就是按部就班的游戏规则了,只要程序按游戏规则走了,那就可以玩了,好了,

做好的东西就先上一下了(由于初步完成而已,其中还有很多需要优化的,后期在来了,起初为了方便测试,没做数据库,

有时间在完成这些步骤了) ;如下连接
http://download.csdn.net/detail/mojiewen2006/4286031 ,后期的修改暂不放上来了,

CSDN不让删除,太多了不好

用到的图片如下



class Card // 牌类

{

public:

Card(){m_select=false;}

void SetPos(int xpos,int ypos) // 设置坐标位置

{

m_xpos=xpos;

m_ypos=ypos;

}

int GetValue(){return m_card;}

bool IsSelect(){return m_select;}

int GetxPos() // 获取x坐标

{

return m_xpos;

}

int GetyPos() // 获取y坐标

{

return m_ypos;

}

int GetxFrame() // 获取图片所在x块

{

return m_xframe;

}

int GetyFrame() // 获取图片所在y块

{

return m_yframe;

}

void Onclick(int xpos,int ypos,bool lastcard=false); // 鼠标单击判断

void IntToPos(int card); // 设置牌值

Card& operator = (const Card& other); //重载=号,用于排序

bool operator< (const Card& other) ; // 重载此运算符只为排序牌值及后面的出牌判断,不做其他用

private:

int m_card; // 牌的数值

int m_xpos; // 牌显示x坐标

int m_ypos; // 牌显示y坐标

bool m_select; // 牌是否被选中,用于出牌判断

int m_xframe; // 对应图片坐标x位置

int m_yframe; // 对应图片坐标y位置

int m_split; // 大小区分

};

如下为它的一些函数

Card& Card::operator = (const Card& other) //重载=号,用于排序

{

m_card=other.m_card; // 牌值

m_xframe=other.m_xframe ; // 对应图片中的x轴块

m_yframe=other.m_yframe ; // 对应图片中的y轴块

m_xpos=other.m_xpos; // 显示的x坐标

m_ypos=other.m_ypos ; // 显示的y坐标

m_select=other.m_select ; // 图片是否被选中

m_split=other.m_split ; // 以什么值分开区别牌的大小

return *this;

}

bool Card::operator< (const Card& other) // 重载此运算符只为排序牌值及后面的出牌判断,不做其他用

{

if(4==m_yframe) // 假如在大猫或小猫一行

{

if(m_yframe==other.m_yframe) // 假如另一张牌也是王

{

if(m_xframe<other.m_xframe )

return true;

else

return false;

}

else // if(m_xframe>other.m_xframe )

{

return false;

}

}

else if(4==other.m_yframe) // 假如第二张牌为王

{

return true;

}

else // 两张牌都不是王

{

if(m_split>=m_xframe) // 从4分开大小

{

if(m_split>=other.m_xframe) // 另一张牌也是在 1,2,3内

{

if(m_xframe<other.m_xframe) // 假如小于

{

return true;

}

else if(m_xframe==other.m_xframe) // 假如牌面相等

{

if(m_yframe<other.m_yframe) // 判断花色

return true ;

else

return false;

}

else // 假如大于

{

return false;

}

}

else if(m_split<other.m_xframe)

{

return false;

}

}

else // 假如牌值不在1,2,3内

{

if(m_split<other.m_xframe) // 另一张牌也不在 1,2,3内

{

if(m_xframe<other.m_xframe) // 假如小于

{

return true;

}

else if(m_xframe==other.m_xframe) // 假如牌面相等

{

if(m_yframe<other.m_yframe) // 判断花色

return true ;

else

return false;

}

else // 假如大于

{

return false;

}

}

else if(m_split>=other.m_xframe) // 另一张牌在1,2,3内

{

return true;

}

}

}

return true;

}

void Card::Onclick(int xpos,int ypos,bool lastcard)

{

if(!lastcard) // 是否最后一张牌,需要特殊处理,此处为不是最后一张牌

{

if(m_select) // 假如选中,开始判断

{

if( (m_xpos<xpos && xpos<(m_xpos + bmCard.GetWidth ()) && m_ypos<ypos && ypos<(m_ypos + CardSpace ) )

|| (m_xpos<xpos && xpos<(m_xpos + CardSpace) && m_ypos < ypos && ypos< (m_ypos + bmCard.GetHeight ()))

)

{

m_xpos=m_xpos;

m_ypos=m_ypos+CardSpace; // 将原来的坐标向下移

m_select=!m_select;

}

}

else // 假如之前未选中

{

if (m_xpos<xpos && xpos<(m_xpos + CardSpace) && m_ypos<ypos && ypos<(m_ypos + bmCard.GetHeight ()) )

{

m_xpos=m_xpos;

m_ypos=m_ypos - CardSpace; // 将原来的坐标向上移

m_select=!m_select;

}

}

}

else // 如果是最后一张牌

{

if(m_select) // 假如选中,开始判断

{

if(m_xpos<xpos && xpos<(m_xpos + bmCard.GetWidth ()) && m_ypos<ypos && ypos<(m_ypos + bmCard.GetHeight () ))

{

m_xpos=m_xpos;

m_ypos=m_ypos+CardSpace; // 将原来的坐标向下移

m_select=!m_select;

}

}

else // 假如之前未选中

{

if (m_xpos<xpos && xpos<(m_xpos + bmCard.GetWidth ()) && m_ypos<ypos && ypos<(m_ypos + bmCard.GetHeight ()) )

{

m_xpos=m_xpos;

m_ypos=m_ypos - CardSpace; // 将原来的坐标向上移

m_select=!m_select;

}

}

}

}

void Card::IntToPos(int card)

{

m_card=card;

m_split=2;

m_xframe=(card-1)%13;

m_yframe=(card-1)/13;

}

程序最终执行结果为

1.服务器



2.客户端

登陆



登陆后



游戏中

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: