C++开发斗地主(QT)第一篇之数据结构

斗地主,是一种在中国流行的纸牌游戏。游戏最少由3个玩家进行,用一副54张牌(连鬼牌),其中一方为地主,其余两家为另一方,双方对战,先出完牌的一方获胜。如今已风靡整个中国,并流行于互联网上!

从今天开始,我将会一步步详细讲解单机斗地主游戏开发过程。该游戏以C++为主,QT做为界面(包括显示 动画 声音等)的Window平台,没有用到第三方面库如CoCo2d 等,至于为什么要用QT,主要是自己得心应手(QT动画 透明 图像处理太简单了),比VS简单,而且还能跨平台,本游戏在最后开源。网上的斗地主算法 源码很多,如果写的不好,欢迎批评 探讨。为了提起大家的兴趣,我给我做好的游戏功能和界面简单给大家看一下:

该游戏的大部分资源都是人网上下载的,如有侵权,请及时通知,我将会删除。本软件主要算法用的是 宽立斗地主AI设计与实现

我在此基础上用QT在Windows上进行了详细开发,主要是为了研究算法,我在此基础上对算法做了适当修改。

游戏主要功能:音效开关  机器人模式  记牌器窗口 退出 功能按键,还有出牌控制 音效 报警等,以后会更加完善,加一些设置,如声音大小  游戏难度 人物选取 等功能。

现在开始来讲游戏的开发过程:

一、数据结构,任何软件开发都离不开数据结构和数据处理。

1.牌型枚举(CardTypes):

//牌型枚举
enum CardTypes
{
    Error_Card,//错误出牌
    Single_Card,//单牌
    Double_Card,//对子
    Three_Card,//三张
    ThreeOne_Card,//三带一
    ThreeTwo_Card,//三代二
    Line_Card,//单顺
    Double_Line_Card,//连对
    Plane_Card,//飞机(两个三张连)
    Plane_TwoSingle_Card,//飞机带俩单
    Plane_TwoDouble_Card,//飞机带两对
    Four_TwoSingle_Card,//四带俩单
    Four_TwoDouble_Card,//四带两对
    Bomb_Card,//炸弹
    Rocket_Card//王炸(火箭)
};

 

我给他们定义了15种牌型:

⒈错误牌型:不能出的牌型

⒉单牌:例一张A

⒊对子:例AA

⒋三张:AAA

⒌三带一:AAAB

⒍三带二:AAABB

⒎单顺:也叫连子3,4,5,6,7&#x

C++写的基于MFC界面的斗地主游戏源码,内含详细注释,附带了简单的AI出牌规则,放出来供大家参考交流。vs2010编写,vs2015测试可用,理论上vs05及以上都可正常编译运行。 void Judge::MainFlow() { switch(DataCenter::Instance().GetPlayState()) { case EM_LandHolderBorn_PlayState: { //先检查是否已经问完了 //遍历玩家检查是否已经询问过了,如果已经都问过了,则设置叫分最高的为地主 BOOL bAllAsked = TRUE;//是否已经询问完了 vector & vecPlayer = DataCenter::Instance().GetPlayerList(); for (UINT i = 0; i m_nCurHighstScore) { m_nCurHighstScore = vecPlayer[i].GetLandOwerScore(); m_pToBeLandOwer = &vecPlayer;[i]; } if (vecPlayer[i].GetLandOwerScore() SetLandOwer(TRUE); } //然后根据情况执行询问流程 //如果地主已经产生,则跳入下一阶段 if (NULL != DataCenter::Instance().GetLandOwner()) { m_pCurPlayer = NULL; DataCenter::Instance().SetPlayState(EM_WaitPlayer_PlayState); MainFlow(); return; } //如果当前player为空,设置当前player为地主牌得主 if (m_pCurPlayer == NULL) { m_pCurPlayer = DataCenter::Instance().GetLandOwnerCardHolder(); } //对当前玩家执行地主问询 ASSERT(m_pCurPlayer); m_pCurPlayer->ExcuteCallLandOwer(); } break; case EM_WaitPlayer_PlayState: { //如果游戏已经结束,则执行结束逻辑 BOOL bLandOwerWin = FALSE; if (DataCenter::Instance().IsOver(bLandOwerWin)) { if (bLandOwerWin) { AfxMessageBox(_T("地主赢了!")); } else { AfxMessageBox(_T("佃户赢了!")); } DataCenter::Instance().SetPlayState(EM_WaitToStart_PlayState); //将所有玩家明牌 DataCenter::Instance().ShowAllPlayerCard(); RefreshView(); return; } //如果是出牌阶段而当前player为空,设置当前player为地主,并发予底牌 if (m_pCurPlayer == NULL) { m_pCurPlayer = DataCenter::Instance().GetLandOwner(); DataCenter::Instance().SendOutBottomCard(); RefreshView(); } ASSERT(m_pCurPlayer); m_pCurPlayer->ExcuteCallCardPlay(); } break; } } void Judge::CurPlayerCallScore(int nScore) { if (m_pCurPlayer == NULL) { ASSERT(FALSE); return; } //将玩家选择的分数设置给玩家 m_pCurPlayer->SetLandOwerScore(nScore); //如果当前玩家为空,直接返回 if(m_pCurPlayer == NULL) { return; } if (nScore == 3) { //如果玩家叫了三分,直接设为地主 m_pCurPlayer->SetLandOwer(TRUE); } else { //玩家叫的不是三分,则记下玩家叫的分数 m_pCurPlayer->SetLandOwerScore(nScore); } if (nScore == 0) { CString strWord; strWord.Format(_T("不叫")); m_pCurPlayer->Say(strWord); } else { CString strWord; strWord.Format(_T("%d分"), nScore); m_pCurPlayer->Say(strWord); } //玩家叫分后隐藏叫地主按钮 Judge::Instance().ShowCallLandOwerBtn(FALSE); //切换到下一个玩家,流程继续 SwitchToNextPlayer(); MainFlow(); }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值