| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 766 人关注过本帖
标题:自己写的控制台下的斗地主~
只看楼主 加入收藏
阿冲
Rank: 2
等 级:论坛游民
帖 子:29
专家分:40
注 册:2009-10-5
结帖率:75%
收藏
 问题点数:0 回复次数:2 
自己写的控制台下的斗地主~
本来是分好几个源文件的,为了方便查看,特意合在一起了~


程序代码:
#include <iostream>
#include <ctime>
using namespace std;
#define NULL 0
typedef struct tagNODE 
{
    bool bOut;  //默认为false 
    int iSize;//牌的大小
    int iValue;//牌的值  1-54 
    char cPai[20]; //棋牌字符
    tagNODE * pNext;//后驱指针
}T_NODE;

class CPaiList
{
protected:
    T_NODE * m_pHead; //头节点
    T_NODE * m_pTail;
public:
    CPaiList();
    ~CPaiList();
    bool ADDNODE(char * pszPai , int iSize , int iValue);//创建棋牌
    bool DELNODE(int iSequence);//删除已出棋牌
    void ShowList();
    T_NODE * GETNODE();

};
class CPaiShow : public CPaiList 
{
public:
    void ADDpai();//随机抽取13颗牌(不算大小花)
    bool DELpai(int iValue , char * szOut);//出牌即删牌
    bool Choose(int iValue);//选择牌
    bool Cancel(int iValue);//取消选择牌
    int ShowPai();//出牌
};
CPaiList::CPaiList()
{
    m_pHead = NULL;
    m_pTail = NULL;
}
CPaiList::~CPaiList()//释放空间
{
    T_NODE * pCulNode = m_pHead;
    T_NODE * pPreNode;
    while (pCulNode)
    {
        pPreNode = pCulNode->pNext;
        delete pCulNode;
        pCulNode = pPreNode;
    }
}
bool CPaiList::ADDNODE(char * pszPai , int iSize , int iValue)//创建牌
{
    T_NODE * pNew = new T_NODE;
    if (pNew == NULL)
    {
        return false;
    }

    strcpy(pNew->cPai , pszPai);    
    pNew->iSize = iSize;
    pNew->iValue = iValue;
    pNew->pNext = NULL;
    pNew->bOut = false;

    if (m_pHead == NULL)
    {
        m_pHead = pNew;        
    } 
    else
    {
        m_pTail->pNext = pNew;        
    }
    m_pTail = pNew;

    return true;
}

bool CPaiList::DELNODE(int iValue)//删除牌
{
    T_NODE * pCulNode = m_pHead;
    T_NODE * pPreNode = m_pHead;
    while (pCulNode)
    {
        
        if (pCulNode->iValue == iValue)
        {
            if (pCulNode == m_pHead)//当前节点等于头节点
            {
                m_pHead = pCulNode->pNext;
            } 
            
            else
            {
                pPreNode->pNext = pCulNode->pNext;
            }
            delete pCulNode;
            return true;        
        }
        pPreNode = pCulNode;
        pCulNode = pCulNode->pNext;
    }
    return false;
}
void CPaiList::ShowList()
{
    T_NODE * pCulNode = m_pHead;
    while(pCulNode)
    {
        cout << pCulNode->cPai << "(" << pCulNode->iValue << ")"  << '\t' ;

        pCulNode = pCulNode->pNext;
    }
}

T_NODE * CPaiList::GETNODE()
{
    return m_pHead;
}
#define ROW 4
#define COL 15

void CPaiShow::ADDpai()
{    

    char * pszPaiA[ROW] = {"红桃","黑桃","方块","草花"};
    char * pszPaiB[COL] = {"3","4","5","6","7","8","9","10","J","Q","K","A","2","小头","大头"};
    char szTmp[10];
    unsigned iPaiA = 0, iPaiB = 0;
    srand( time(0) );
    int iValue;
    int iSize = 13;//随机抽取13颗牌
    int iFlag = 1;//判断是否重复

    while(iSize)
    {    
        iPaiA = rand() % ROW;
        iPaiB = rand() % COL;
        

        if (iPaiB != 13 && iPaiB != 14)//求扑克牌的值1-52
        {
            int iTmp = 0;
            for (int i = 1; i <= 4; ++i)
            {
                for (int j = 1; j <= 13; ++j)
                {
                    ++iTmp;
                    if ((iPaiA + 1) == i && (iPaiB + 1) == j)
                    {
                        iValue = iTmp;
                    }
                }
            }
            
            strcpy(szTmp , pszPaiA[iPaiA]);
            strcat(szTmp , pszPaiB[iPaiB]);    
            
        } 
        else
        {    iValue = iPaiB + 40;
            strcpy(szTmp , pszPaiB[iPaiB]);    
        }
//-------------判断各节点中有无重复的数据,无则继续-----------------------------
         T_NODE * pCulNode = m_pHead;
        
        if (pCulNode == NULL)
        {
            if (iPaiB != 13 && iPaiB != 14)
            {
                --iSize;
            }
            ADDNODE(szTmp , iPaiB , iValue);            
            continue;
         }
 
           while (pCulNode != NULL)
          {
              if (strcmp(pCulNode->cPai , szTmp) == 0)//如果有重复的牌
               {            
                 iFlag = 0;
               }            

              pCulNode = pCulNode->pNext;
           }

         if (iFlag==1)
         {
            if (iPaiB != 13 && iPaiB != 14)
            {
                --iSize;
            }            
            ADDNODE(szTmp , iPaiB , iValue);//添加牌
//---------------------------------------------------------------            
            
            T_NODE * pPreNode = m_pHead;//此处将牌按从大到小的顺序排列起来
            char szPaiTmp[10];
            int iSizeTmp;
            int iValueTmp;
            while (pPreNode)
            {
                T_NODE * pCulNode = m_pHead;
                while (pCulNode)
                {
                    if (pPreNode->iSize > pCulNode->iSize)//如果有前一张牌比后一张牌大,就替换掉
                    {
                        strcpy(szPaiTmp , pCulNode->cPai);    
                        iSizeTmp = pCulNode->iSize;
                        iValueTmp = pCulNode->iValue;
                        //--------------------
                        strcpy(pCulNode->cPai , pPreNode->cPai);    
                        pCulNode->iSize = pPreNode->iSize;
                        pCulNode->iValue = pPreNode->iValue;
                        //--------------------
                        strcpy(pPreNode->cPai , szPaiTmp);    
                        pPreNode->iSize = iSizeTmp;
                        pPreNode->iValue = iValueTmp;
                        
                    }            
                    pCulNode = pCulNode->pNext;
                }
                
                pPreNode = pPreNode->pNext;
            }
//-----------------------------------------
        }
        iFlag=1;//如果有重复的牌此处重设为1
        
    }
    
}
//----------------水平分割线---------------------------------

bool CPaiShow::Choose(int iValue)//选牌
{
    T_NODE * pCulNode = m_pHead;
    while (pCulNode)//把选中的牌做记号
    {
        if (pCulNode->iValue == iValue)
        {
            pCulNode->bOut = true;
            return true;
        }
        pCulNode = pCulNode->pNext;
    }
    return false;
}

bool CPaiShow::Cancel(int iValue)
{
    T_NODE * pCulNode = m_pHead;
    while (pCulNode)//取消选中的牌
    {
        if (pCulNode->iValue == iValue && pCulNode->bOut == true)
        {
            pCulNode->bOut = false;
            return true;
        }
        pCulNode = pCulNode->pNext;
    }
    return false;
}

int CPaiShow::ShowPai()//判断选中的牌是否符合标准
{
    T_NODE * pCulNode = m_pHead;
    T_NODE * pTwoNode = m_pHead;
    int iTmpA = 0 , iTmpB = 0 , iTmpC = 0 , iCount = 0;
    while (pCulNode)//用每张牌来判断
    {
        if (pCulNode->bOut == true)
        {
            ++iCount;//选中的牌数
            
            T_NODE * pPreNode = pCulNode;
            while (pPreNode)
            {
                
                if (pPreNode->bOut == true && pPreNode != pCulNode)
                {
                    
                    if (pCulNode->iSize == pPreNode->iSize )//判断选中的牌中有几个对子
                    {
                        ++iTmpA;                            
                    }
                    if (pCulNode->iSize - pPreNode->iSize  == 1)//前一张比后一张小1,判断单顺子
                    {
                        ++iTmpB;
                    }
                    if (pTwoNode->iSize != pCulNode->iSize && pCulNode->iSize - pPreNode->iSize == 1)//判断双顺子
                    {
                        ++iTmpC;
                    }
                }                                            
                
                pPreNode = pPreNode->pNext;
            }
            
            
            
        }    
        pTwoNode = pCulNode;
        pCulNode = pCulNode->pNext;
    }
//-----------------------------------------------
    int iTmp = 0;
    if (iCount == 1)//单颗
    {
        iTmp = 1;
    }
    
    if (iCount == 2 && iTmpA == 1)//两张一对
    {
        iTmp = 2;
    }
    
    if (iCount == 4 && iTmpA == 3)//三带一
    {
        iTmp = 3;
    }
    
    if (iCount == 4 && iTmpA == 6)//四颗一样的是炸弹
    {
        iTmp = 4;
    }
    
    if (iCount >= 5 && iTmpB + 1 == iCount)//单顺子必须大等于五颗牌
    {
        iTmp = 5;
    }
    
    if (iCount >= 4 && iTmpC + 2 == iCount)//双顺子必须大等于四颗牌
    {
        iTmp = 6;
    }
    return iTmp;
}

int main()
{
    int iValue;
    char szCancel[2];
    char szOut[2];
    CPaiShow obj;
    obj.ADDpai();
    obj.ShowList();
    
    while (1)
    {
        cout << endl;
        cout << "按括号内的数字输入您要选择的牌:";
        cin >> iValue;
        if (obj.Choose(iValue))
        {
            cout << "选择成功" << endl;                        
        }
        else
        {
            cout << "对不起,没有此牌" << endl;
        }

        cout << "是否要取消已选择的牌?是按Y,否则请按其他键:";
        cin >> szCancel;
        if (strcmp(szCancel , "Y") == 0 || strcmp(szCancel , "y") == 0)
        {
            cout << "请输入您要取消的牌:";
            cin >> iValue;
            if (obj.Cancel(iValue))
            {
                cout << "已取消" << endl;
            } 
            else
            {
                cout << "对不起,您未选择此牌" << endl;
            }
        }



        T_NODE * pCulNode = obj.GETNODE();//显示
        while (pCulNode)
        {
            if (pCulNode->bOut == true)
            {
                cout << "选中的牌有:" << pCulNode->cPai << endl;
            }
            pCulNode = pCulNode->pNext;
        }


        cout << "按Y键确认出牌,否则请按其他键:";
        cin >> szOut;

        if (strcmp(szOut , "Y") == 0 || strcmp(szOut , "y") == 0)
        {        
            int iTmp = obj.ShowPai();
            if (iTmp)
            {
                cout << "出牌成功" << endl;
                switch (iTmp)
                {
                    case 1 :
                        cout << "您出的是单张" << endl;
                        break;
                    case 2 :
                        cout << "您出的是对子" << endl;
                        break;
                    case 3 :
                        cout << "您出的是三带一" << endl;
                        break;
                    case 4 :
                        cout << "您出的是炸弹" << endl;
                        break;
                    case 5 :
                        cout << "您出的是单顺子" << endl;
                        break;
                    case 6 :
                        cout << "您出的是双顺子" << endl;
                        break;
                }
            }
            else
            {
                cout << "选牌不对,请重选~" << endl;
            }
//---------------------这里用不用单独写个函数?-----------------------------------------
            T_NODE * pCulNode = obj.GETNODE();
            T_NODE * pPreNode;
            while (pCulNode)
            {
                pPreNode = pCulNode->pNext;
                if (pCulNode->bOut)
                {
                    obj.DELNODE(pCulNode->iValue);
                }
                pCulNode = pPreNode;
            }
//----------------------------------------------------------------------------------
        }

        if (obj.GETNODE() == NULL)//如果牌都出光了,就退出游戏
        {
            cout << "游戏结束" << endl;
            break;
        }
        obj.ShowList();
    }
    
    return 0;
}
搜索更多相关主题的帖子: 斗地主 
2009-11-19 07:47
mtlppp
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2009-11-19
收藏
得分:0 
牛!~~楼主实验过了吗!?~
2009-11-19 12:25
阿冲
Rank: 2
等 级:论坛游民
帖 子:29
专家分:40
注 册:2009-10-5
收藏
得分:0 
嗯,测试成功~
2009-11-23 07:54
快速回复:自己写的控制台下的斗地主~
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027773 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved