| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 782 人关注过本帖, 1 人收藏
标题:优化后的斗地主~自己写的~
只看楼主 加入收藏
阿冲
Rank: 2
等 级:论坛游民
帖 子:29
专家分:40
注 册:2009-10-5
结帖率:75%
收藏(1)
 问题点数: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 ADDNODE(char * pszPai , int iValue);
    bool DELNODE(int iSequence);//删除已出棋牌
    void ShowList();
    T_NODE * GETNODE();

};
class CPaiShow : public CPaiList 
{
public:
//    void ADDpai();//随机抽取13颗牌(不算大小花)
    void DELpai();//出牌即删牌
    bool Steup(int iValue);//设置选择或取消
    int ShowPai();//运算是否可出牌
    void ShowOuting();  //显示选中将要出的牌
    void ShowCate(int iValue);//出牌类型
    void InitPai();  //默认一副牌
    void TakePai(int arrPai[]);//分牌
    void SizePai(int iValue , int & iSize , char * szTmp , char * pszPaiA);//判断牌的大小和牌名
};


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 PAINUMS 54 //54张牌
#define REN 4 //4个人打牌


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;
}

void CPaiShow::DELpai()
{
    T_NODE * pCulNode = m_pHead;
    T_NODE * pPreNode;
    while (pCulNode)
    {
        pPreNode = pCulNode->pNext;
        if (pCulNode->bOut)
        {
            DELNODE(pCulNode->iValue);
        }
        pCulNode = pPreNode;
    }
}


bool CPaiShow::Steup(int iValue)//选牌或取消
{
    T_NODE * pCulNode = m_pHead;
    while (pCulNode)
    {
        if (pCulNode->iValue == iValue)
        {
            if (pCulNode->bOut)
            {
                pCulNode->bOut = false;//如果该牌被选择,则取消
            }
            else
            {
                pCulNode->bOut = true;//如果该牌未被选择,则选中
            }
            return true;
        }
        pCulNode = pCulNode->pNext;
    }    
    return false;
}

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

void CPaiShow::ShowCate(int iValue)
{
    if (iValue)
    {
        cout << "出牌成功" << endl;
        switch (iValue)
        {
            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;
    }
}

void CPaiShow::InitPai()  //默认一副牌打乱数字
{
    bool bFlag[PAINUMS] = {0};
    int arrPai[PAINUMS]; 
    int iWhile = PAINUMS , iArr = 0 , iPai = 0 ;
     srand( time(0) );

    while (iWhile)
    {
        iPai = rand() % PAINUMS + 1;
        if (!bFlag[iPai-1])
        {
            bFlag[iPai-1] = true;
            arrPai[iArr] = iPai;
            --iWhile;
             ++iArr;
        }            
         

    }
    TakePai(arrPai);

}

void CPaiShow::TakePai(int arrPai[])//分牌并按顺序插牌
{
    char szTmp[10];
    char * pszPaiA[] = {"红桃","黑桃","方块","草花"};

    

    int iSize;

    int iSets = PAINUMS / 54 * 2;//用总的牌数除一套牌的牌数再加二得大小花的数量

     for (int i = 1 ; i <= PAINUMS ; ++i)//所有的牌数减去大小头
    {
        if (i % 4 == 1)//1代表坐位,如1号坐是1,2号坐是2,3号坐是3,4号坐是4
        {
            int iPaiA = arrPai[i-1] / 13;
            if (iPaiA > 3)//防止下标越界
            {
                iPaiA = 3;
            }
            SizePai(arrPai[i-1] , iSize , szTmp , pszPaiA[iPaiA]);
            //SizePai(arrPai[i-1] , iSize , szTmp , "草花");

//-----------------------开始排序插牌------------------
            int iTmp = 1;
            
            T_NODE * pPreNode = m_pHead;//定义当前节点
            T_NODE * pCulNode = m_pHead;//定义尾节点
            while (pPreNode)
            {
                if (iSize > pPreNode->iSize)//做一个循环当牌值大于第一个牌的时候操作并退出
                {
                    T_NODE * pNewNode = new T_NODE;//创建一个新节点
                    if (pPreNode == m_pHead)//如果当前节点是头节点,则让新节点为头节点
                    {
                        m_pHead = pNewNode;
                    }
                    else//否则尾节点的后驱指针等于当前节点
                    {
                        pCulNode->pNext = pNewNode;
                    }
                    
                    pNewNode->pNext = pPreNode;//新节点的后驱指针等于当前节点
                    
                    strcpy(pNewNode->cPai , szTmp);//将新节点赋值
                    pNewNode->iValue = arrPai[i-1];
                    pNewNode->bOut = false;
                    pNewNode->iSize = iSize;
                    iTmp = 0;//将临时变量赋0,让它不能创建
                    break;//退出,这里很重要!
                }    
                pCulNode = pPreNode;
                pPreNode = pPreNode->pNext;
            }        
            
            if (iTmp == 1)
            {
                ADDNODE(szTmp , iSize , arrPai[i-1]);//添加牌
                
            }

            //---------------------插牌结束-----------------------------


        }        
    }        


}


void CPaiShow::SizePai(int iValue , int & iSize , char * szTmp , char * pszPaiA)//求牌大小和牌名
{
    if (iValue > PAINUMS - PAINUMS / 54 * 2)//一套牌54张,用54减去大小头的数量得剩下的数量
    {
        for (int i=1; i <= PAINUMS / 54 * 2; ++i)
        {
            if (i % 2 == 0)
            {
                strcpy(szTmp , "大花"); 
                iSize = 17;
            }
            else
            {
                strcpy(szTmp , "小花"); 
                iSize = 16;
            }
        }
    }
    else
    {
        strcpy(szTmp , pszPaiA); 
        iSize = iValue % 13;
        char szValue[10];
        sprintf(szValue , "%d" , iSize);

        switch (iSize)
        {
        case 11:
            strcat(szTmp , "J"); 
            break;
        case 12:
            strcat(szTmp , "Q"); 
            break;
        case 0:
            iSize = 13;
            strcat(szTmp , "K"); 
            break;
        case 1:
            iSize = 14;
            strcat(szTmp , "A"); 
            break;
        case 2:
            strcat(szTmp , "2"); 
            iSize = 15;
            break;
        default:
            strcat(szTmp , szValue); 
        }
    }    
}



int main()
{
    int iValue;
    char szOut[2];
    CPaiShow obj;

    obj.InitPai();


    obj.ShowList();

    while (1)
    {
        cout << endl;

        cout << "请输入您想选择或取消的牌:";
        cin >> iValue;
        
        if (obj.Steup(iValue))
        {
            cout << "操作成功" << endl;    
        }
        else
        {
            cout << "没有此牌" << endl;    
        }

        obj.ShowOuting();//显示选中的牌。

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

        if (strcmp(szOut , "Y") == 0 || strcmp(szOut , "y") == 0)
        {        
            obj.ShowCate(obj.ShowPai());//显示出牌信息
//---------------------------------------------------------------
            obj.DELpai();//删除选中牌
//----------------------------------------------------------------------------------
        }
        
        if (obj.GETNODE() == NULL)//如果牌都出光了,就退出游戏
        {
            cout << "游戏结束" << endl;
            break;
        }
        obj.ShowList();
    }

    return 0;
}
收到的鲜花
搜索更多相关主题的帖子: 斗地主 
2009-11-23 13:32
flyingcloude
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:6
帖 子:598
专家分:1512
注 册:2008-1-13
收藏
得分:0 
搞个有界面的,让我玩的开心些

你能学会你想学会的任何东西,这不是你能不能学会的问题,而是你想不想学的问题
2009-11-23 21:16
王博锐
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2016-1-7
收藏
得分:0 
2016-01-07 10:55
快速回复:优化后的斗地主~自己写的~
数据加载中...
 
   



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

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