cocos2dx《单机斗地主》源码解剖之七 对电脑玩家手中的牌进行分拆

在电脑玩家跟牌和出牌之前首先对电脑玩家的牌进行拆分:

根据文档需求(见本博客“斗地主规则“)拆分牌按以下顺序,先分析炸弹---飞机---连对---连牌--三带,对子,单张。请看如下代码:

void GameScene::FenChaiNpcPai(Player* npc){
    /************************************************************************/
    /* 1.首先分析出来牌的类型(如:四张,三张,两张,一张)                                              */
    /************************************************************************/
    std::vector<PaiXing> vec;
    PaiXing xing;
    CCArray* arr = CCArray::create();//临时数组
    arr->addObjectsFromArray(npc->getArrPk());
    //提取双鬼
    Poker* pk = (Poker *)arr->objectAtIndex(0);
    Poker* pk1 = (Poker *)arr->objectAtIndex(1);
    if(pk->getHuaSe() == Gui && pk1->getHuaSe() == Gui){
        xing.type = BOMB_CARD;
        xing.vec.push_back(pk);
        xing.vec.push_back(pk1);
        arr->removeObject(pk);
        arr->removeObject(pk1);
        vec.push_back(xing);
    }
    //分析牌型
    for(int i=0; i<arr->count();)
    {
        pk = (Poker*)arr->objectAtIndex(i);
        xing.vec.clear();//清除数组
        //找出与pk相同的牌
        for (int j=i; j<arr->count(); ++j)
        {
            pk1 = (Poker*)arr->objectAtIndex(j);
            if(pk->getNum() == pk1->getNum())
            {
                ++i;
                xing.vec.push_back(pk1);
            }
            else
            {
                break;
            }
        }
        if(xing.vec.size() == 4)
            xing.type = BOMB_CARD;
        if(xing.vec.size() == 3)
            xing.type = THREE_CARD;
        if(xing.vec.size() == 2)
            xing.type = DOUBLE_CARD;
        if(xing.vec.size() == 1)
            xing.type = SINGLE_CARD;
        vec.push_back(xing);
    }
    /************************************************************************/
    /* 2.按优先级(先分析炸弹---飞机---连对---连牌--三带,对子,单张)提取牌型并保存用于出牌或跟牌                               */
    /************************************************************************/
    //提取炸弹
    for(std::vector<PaiXing>::iterator iter = vec.begin(); iter != vec.end(); )
    {
        if(iter->type == BOMB_CARD)
        {
            xing.type = BOMB_CARD;
            xing.vec.clear();
            xing.vec = iter->vec;
            npc->m_vecPX.push_back(xing);//把牌型保存到用户数组中
            iter = vec.erase(iter);
        }
        else
        {
            ++iter;
        }
    }
    //提取飞机
    TiQuFeiJi(npc,THREE_CARD,vec);
    //提取连对
    TiQuLianDui(npc,vec);
    //提取连牌
    TiQuLianPai(npc,vec);
    //剩余的是三带,对子,单张 全部加入npc牌型中
    for(std::vector<PaiXing>::iterator iter = vec.begin(); iter != vec.end();)
    {
        npc->m_vecPX.push_back(*iter);
        iter = vec.erase(iter);
    }
    //排序
    stable_sort(npc->m_vecPX.begin(),npc->m_vecPX.end(),isShorter1);
}

最后按每个牌型的值从小到大进行排序。

提取飞机代码:

void GameScene::TiQuFeiJi(Player* npc,CARD_TYPE type,std::vector<PaiXing> &vec){
    Poker * pk = NULL;
    PaiXing xing;
    for (std::vector<PaiXing>::iterator iter=vec.begin(); iter != vec.end();)
    {
        if(pk == NULL && iter+1 == vec.end())
            break;
        if(pk == NULL && iter->type == type && (iter+1)->type == type)
        {
            Poker* pk1 = iter->vec.front();
            Poker* pk2 = (iter+1)->vec.front();
            if(pk1->getNum()-1 == pk2->getNum())
            {
                pk = pk2;
                xing.type = AIRCRAFT_CARD;
                xing.vec.clear();
                xing.vec = iter->vec;
                iter = vec.erase(iter);
                xing.vec.insert(xing.vec.end(),iter->vec.begin(),iter->vec.end());
                iter = vec.erase(iter);
            }
        }
        if(pk != NULL)
        {
            if(iter == vec.end())
            {
                npc->m_vecPX.push_back(xing);
                break;
            }

            Poker* pk1 = iter->vec.front();
            if(iter->type == type && pk->getNum()-1 == pk1->getNum())
            {
                pk = pk1;
                xing.vec.insert(xing.vec.end(),iter->vec.begin(),iter->vec.end());
                iter = vec.erase(iter);
                if(iter == vec.end())
                {
                    npc->m_vecPX.push_back(xing);
                    break;
                }
            }
            else
            {
                npc->m_vecPX.push_back(xing);
                pk = NULL;
            }
        }
        else
        {
            ++iter;
        }
    }
}

提取连对 代码:

void GameScene::TiQuLianDui(Player* npc,std::vector<PaiXing> &vec){
    std::vector<PaiXing> vecTem;//临时数组
    std::vector<PaiXing> vecFan;//存放要重新返还vec里的牌
    Poker* pk = NULL;
    for(std::vector<PaiXing>::iterator iter = vec.begin(); iter != vec.end();)
    {
        //将相连的牌加入临时数组中
        Poker* pk1 = iter->vec.front();
        if((iter->type == THREE_CARD || iter->type == DOUBLE_CARD) && (pk == NULL || (pk->getNum()-1 == pk1->getNum() && pk->getNum() < Er)))
        {
            pk = pk1;
            vecTem.push_back(*iter);
            iter = vec.erase(iter);
        }
        else
        {
            if(pk == NULL)
                ++iter;
            pk = NULL;
            if(vecTem.size() >= 3)
            {
                PaiXing xing;
                xing.type = COMPANY_CARD;
                for (int i=0; i<vecTem.size(); ++i)
                {
                    if(vecTem[i].type == THREE_CARD)
                    {
                        //将多余的一张保存返回数组vecFan中
                        PaiXing xing1;
                        xing1.type = SINGLE_CARD;
                        xing1.vec.push_back(vecTem[i].vec.back());
                        vecTem[i].vec.pop_back();
                        vecFan.push_back(xing1);
                        //将剩余两张保存xing中
                        xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                    }
                    if(vecTem[i].type == DOUBLE_CARD)
                    {
                        xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                    }
                }
                vecTem.clear();
                npc->m_vecPX.push_back(xing);
            }
            else if(!vecTem.empty())
            {
                vecFan.insert(vecFan.end(),vecTem.begin(),vecTem.end());
                vecTem.clear();
            }
        }
    }
    if(!vecTem.empty())
    {
        if(vecTem.size() >= 3)
        {
            PaiXing xing;
            xing.type = COMPANY_CARD;
            for (int i=0; i<vecTem.size(); ++i)
            {
                if(vecTem[i].type == THREE_CARD)
                {
                    //将多余的一张保存返回数组vecFan中
                    PaiXing xing1;
                    xing1.type = SINGLE_CARD;
                    xing1.vec.push_back(vecTem[i].vec.back());
                    vecTem[i].vec.pop_back();
                    vecFan.push_back(xing1);
                    //将剩余两张保存xing中
                    xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                }
                if(vecTem[i].type == DOUBLE_CARD)
                {
                    xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                }
            }
            vecTem.clear();
            npc->m_vecPX.push_back(xing);
        }
        else if(!vecTem.empty())
        {
            vecFan.insert(vecFan.end(),vecTem.begin(),vecTem.end());
            vecTem.clear();
        }
    }
    //将vecFan返回到vec数组中并从大到小排序
    if(!vecFan.empty())
    {
        vec.insert(vec.end(),vecFan.begin(),vecFan.end());
        stable_sort(vec.begin(),vec.end(),isDaDaoXiao);
    }
}

提取连牌 代码:

void GameScene::TiQuLianPai(Player* npc,std::vector<PaiXing> &vec){
    std::vector<PaiXing> vecTem;//临时数组
    std::vector<PaiXing> vecFan;//存放要重新返还vec里的牌
    Poker* pk = NULL;
    for(std::vector<PaiXing>::iterator iter = vec.begin(); iter != vec.end();)
    {
        //将相连的牌加入临时数组中
        Poker* pk1 = iter->vec.front();
        if((iter->type == THREE_CARD || iter->type == DOUBLE_CARD || iter->type == SINGLE_CARD) && (pk == NULL || (pk->getNum()-1 == pk1->getNum() && pk->getNum() < Er)))
        {
            pk = pk1;
            vecTem.push_back(*iter);
            iter = vec.erase(iter);
        }
        else
        {
            if(pk == NULL)
                ++iter;
            pk = NULL;
            if(vecTem.size() >= 5)
            {
                PaiXing xing;
                xing.type = CONNECT_CARD;
                for (int i=0; i<vecTem.size(); ++i)
                {
                    if(vecTem[i].type == THREE_CARD)
                    {
                        //将多余的两张保存返回数组vecFan中
                        PaiXing xing1;
                        xing1.type = DOUBLE_CARD;
                        xing1.vec.push_back(vecTem[i].vec.back());
                        vecTem[i].vec.pop_back();
                        xing1.vec.push_back(vecTem[i].vec.back());
                        vecTem[i].vec.pop_back();
                        vecFan.push_back(xing1);
                        //将剩余一张保存xing中
                        xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                    }
                    if(vecTem[i].type == DOUBLE_CARD)
                    {
                        //将多余的一张保存返回数组vecFan中
                        PaiXing xing1;
                        xing1.type = SINGLE_CARD;
                        xing1.vec.push_back(vecTem[i].vec.back());
                        vecTem[i].vec.pop_back();
                        vecFan.push_back(xing1);
                        //将剩余一张保存xing中
                        xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                    }
                    if(vecTem[i].type == SINGLE_CARD)
                        xing.vec.push_back(vecTem[i].vec.front());
                }
                vecTem.clear();
                npc->m_vecPX.push_back(xing);
            }
            else if(!vecTem.empty())
            {
                vecFan.insert(vecFan.end(),vecTem.begin(),vecTem.end());
                vecTem.clear();
            }
        }
    }
    if(!vecTem.empty())
    {
        if(vecTem.size() >= 5)
        {
            PaiXing xing;
            xing.type = CONNECT_CARD;
            for (int i=0; i<vecTem.size(); ++i)
            {
                if(vecTem[i].type == THREE_CARD)
                {
                    //将多余的两张保存返回数组vecFan中
                    PaiXing xing1;
                    xing1.type = DOUBLE_CARD;
                    xing1.vec.push_back(vecTem[i].vec.back());
                    vecTem[i].vec.pop_back();
                    xing1.vec.push_back(vecTem[i].vec.back());
                    vecTem[i].vec.pop_back();
                    vecFan.push_back(xing1);
                    //将剩余一张保存xing中
                    xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                }
                if(vecTem[i].type == DOUBLE_CARD)
                {
                    //将多余的一张保存返回数组vecFan中
                    PaiXing xing1;
                    xing1.type = SINGLE_CARD;
                    xing1.vec.push_back(vecTem[i].vec.back());
                    vecTem[i].vec.pop_back();
                    vecFan.push_back(xing1);
                    //将剩余一张保存xing中
                    xing.vec.insert(xing.vec.end(),vecTem[i].vec.begin(),vecTem[i].vec.end());
                }
                if(vecTem[i].type == SINGLE_CARD)
                    xing.vec.push_back(vecTem[i].vec.front());
            }
            vecTem.clear();
            npc->m_vecPX.push_back(xing);
        }
        else if(!vecTem.empty())
        {
            vecFan.insert(vecFan.end(),vecTem.begin(),vecTem.end());
            vecTem.clear();
        }
    }
    //将vecFan返回到vec数组中并从大到小排序
    if(!vecFan.empty())
    {
        vec.insert(vec.end(),vecFan.begin(),vecFan.end());
        stable_sort(vec.begin(),vec.end(),isShorter1);
    }
}
时间: 2024-12-11 17:16:48

cocos2dx《单机斗地主》源码解剖之七 对电脑玩家手中的牌进行分拆的相关文章

cocos2dx《单机斗地主》源码解剖之八 电脑玩家出牌与跟牌(结束)

上一篇文章对玩家手中的牌进行分析归类,下面就该实现电脑玩家出牌与跟牌的策略了.首先我们来看看出牌的策略,代码如下: void GameScene::update(float delta){ switch (m_iState) { case 0: SendPk(); break; case 1: schedule(schedule_selector(GameScene::Call),1); break; case 2: scheduleOnce(schedule_selector(GameScen

cocos2d-x 之 CCArray 源码分析

cocos2d-x 自己实现了一个数组CCArray ,下面我们来分析一下CCArray的源码 CCArray继承CCObject,所以,CCArray也具有引用计数功能和内存自动管理功能. 数组的源码如下: class CC_DLL CCArray : public CCObject { public: /************************************************************************/ /* 构造析构函数 */ /*******

C# 网络斗地主源码开源

C# 网络斗地主源码开源多线程 讨论交流及  下载地址 可以发送聊天消息

Cocos2d-X手游源码/iOS/Android/cocos2dx源码/AppStore/手游资源“集中营”

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 如果文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额随意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源码下载:点我传送 游戏开发程序猿加班熬夜伤脑筋伤身体,花钱买技术,不如买游戏源代码. 节省开发周期和大量资金投入(工资.测试.学习),可以腾出大量时间精力和女友约会聊天,放松心情! 现在放出多套精品游戏cocos2d-x源代码. 大小游戏可以换皮上线!可学习 二次开发! 完整可编译,游戏体验安装包在网盘里放着,需要的看看. 店铺

Cocos2dx 3.6源码编译错误:syntax error : missing &#39;)&#39; before &#39;{&#39;

在编译Cocos2dx 3.6版本时,发现编译错误: 定位代码行: debugForNormalSprite->drawPoints(positions, 4, 8, Color4F{0.0,1.0,1.0,1.0}); 修改如下: debugForNormalSprite->drawPoints(positions, 4, 8, Color4F<span style="color:#ff0000;">(</span>0.0,1.0,1.0,1.0&

自己收集的十几个cocos2d-x的游戏源码

====================问题描述==================== 自己收集的十几个cocos2d-x的游戏源码,想要的留下邮箱,每天晚上发送! ====================解决方案1==================== 向楼主学习,谢谢,[email protected] ====================解决方案2==================== 楼主好人 [email protected] ====================解决方案

cocos2d-x 手游源码站

尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/37829061 1.魔幻方块 链接:魔幻方块源码 关键词:魔幻方块源码 源代码 Cocos2d-x2.0 游戏源码 益智 休闲 游戏 游戏类型:休闲益智 游戏使用引擎:Cocos2d-x V2.0 代码平台:Windows VS2012 版权说明:该游戏由本人开发,买家购买后可任意使用代码(但不能转卖.不能使用相关资源文件用于商业用途). 游戏版本:V

cocos2dx《单机斗地主》源码解剖之六 玩家(人)的出牌(2)

下面分析//牌的张数大于等于5张的类型判断,原代码如下: int GameScene::PaiDuanPaiXing(){ //对出的牌进行排序 PlayerOutPaiXu(m_arrPlayerOut); //牌型判断 int lengh = m_arrPlayerOut->count(); PaiXing px; //牌的张数少于5张类型判断 单,对,三张,四张 if(lengh<5 && lengh>0){ Poker* pk = (Poker *)m_arrPl

5 cocos2dx 3.0源码分析 渲染 render

渲染,感觉这个挺重要了,这里代入一个简单的例子 Sprite 建立及到最后的画在屏幕上, 我们描述一下这个渲染的流程: 1 sprite 初始化(纹理, 坐标,及当前元素的坐标大小信息) 2 主循环调用sprite的draw(), 把绘制命令发送到系统的render的渲染队列中. 3 Render拿到渲染队列中的渲染命令, 分别对每个命令进行处理, 我们这里的QUAD_COMMAND, 把这个命令中的坐标信息复制到自己的渲染缓冲中, 之后通过调用OpenGL命令对当前的矩形进行绘制. 1 Spr