房卡麻将分析系列之"发牌器"算法设计

    xiaoxiao2021-03-25  128

                   房卡麻将分析系列之"发牌器"算法设计

                  大家好,经过一段时间的努力,在填平了大部分源码框架中的坑后,我们的”大赢家“红中麻将总算完成了1.0版本,虽然仍然有诸多问题,但总归算是有一个好的开始,希望后续诸事顺利,能够早日跑出流水,也欢迎各位合作商积极与我联系。

                   回顾开发过程,我深深的体会到,一个有多年摸牌经验的服务器主程是有多么重要!记得年前帮一家公司做房卡麻将项目,对方从上到下,基本没人会玩麻将,诸事都需要请教麻友,这样的情况我觉得上线的产品应该也不太会好吧,没爱的设计~!不过我可是8岁就上牌桌,八十年代家里就有了一幅竹制麻将。而童年时每年最开心的事情,莫过于过年时和小伙伴们”搓麻“赌压岁钱了。上大学离家之前的十几年里,时常家里”叮叮咣咣“的”呼啦“声是我人生最重要的记忆了。现在的我,虽然一年也打不上两圈牌了,但是仍然可以不看牌面的情况下用手摸出每一张牌。

                                 

                     在这种情况下,写麻将似乎是得心应手的事情。而在碰到胡牌算法调试时,快速理解并写出对应的发牌器算法,也是很有意思并且实用的事情。

                      ”发牌器“就是一套能够对所有操作需求生成出给玩家相应牌型的算法。对于棋牌开发者来说,这是必不可少的,他可以快速的帮助开发者调试出吃,碰,杠,听,胡等各个操作的正确性。节省调试的时间和成本。试想下,如果你让测试员自已打出”天胡“,这似乎是比登天还难的事情罢~。

                      今天,我们就来讲一下“发牌器”的开发原理和设计方法。

                      ”发牌器“的算法基于现有的麻将牌逻辑类扩展出一些函数即可,然后在。比如这样:

                  在原本随机发牌函数的基础上增加各个牌型的发牌函数即可。然后就是为每个函数完成相应的牌型安排。

                 比如,“七对子”牌型:

    //牌型发牌 - 七对子

    void CGameLogic::SetCardData_QiDuiZi(BYTE cbLeftCardCount, BYTE cbCardData[], BYTE cbMaxCount)

    {

    //座位

    BYTE cbChar = 0;

    //玩家的牌

    //玩家1: 饼对,八饼对,四万对,五万对,二条对,四对,还有一个九饼待配对

    BYTE cbP1PaiData[13] = { 0x04, 0x04, 0x08, 0x08, 0x09, 0x14, 0x14, 0x15, 0x15, 0x22, 0x22, 0x24, 0x24 };

    BYTE cbP2PaiData[13] = { 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x15, 0x15, 0x27, 0x27, 0x28, 0x28, 0x19 };

    BYTE cbP3PaiData[13] = { 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x27, 0x27, 0x29, 0x29, 0x33 };

    BYTE cbP4PaiData[13] = { 0x31, 0x31, 0x31, 0x32, 0x33, 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x44, 0x44 };

    //发给玩家的牌

    BYTE cbP1QiPai = 0x09;  //玩家起牌自摸。

    BYTE cbP2QiPai = 0x09  ;//玩家起牌打出去吃胡。

    BYTE cbP3QiPai = 0x23; 

    BYTE cbP4QiPai = 0x04; 

    BYTE cbP5QiPai = 0x19; 

    BYTE cbP6QiPai = 0x26; 

    BYTE cbP7QiPai = 0x33;

    BYTE cbP8QiPai = 0x28;

     

            //填充到发牌的手牌数据里。

    CopyMemory(&cbCardData[cbLeftCardCount - (MAX_COUNT - 1)], cbP1PaiData, sizeof(cbP1PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 2 * (MAX_COUNT - 1)], cbP2PaiData, sizeof(cbP2PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 3 * (MAX_COUNT - 1)], cbP3PaiData, sizeof(cbP3PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1)], cbP4PaiData, sizeof(cbP4PaiData));

           //填充到起牌的数据前八个牌里面。

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 1] = cbP1QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 2] = cbP2QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 3] = cbP3QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 4] = cbP4QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 5] = cbP5QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 6] = cbP6QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 7] = cbP6QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 8] = cbP6QiPai;

    }

              这样在牌局开始时,四个玩家即按如上牌型得到手牌牌墙,并按设定的起牌摸牌。这样即可快速进行七小对的测试。

             再来看一个“杠底开花”

    //牌型发牌 - 杠上开花

    void CGameLogic::SetCardData_GangShangKaiHua(BYTE cbLeftCardCount, BYTE cbCardData[], BYTE cbMaxCount)

    {

    //座位

    BYTE cbChar = 0;

    //玩家的牌

    //玩家1:一饼三个待杠

    BYTE cbP1PaiData[13] = { 0x01, 0x01, 0x01, 0x02, 0x02, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x31, 0x31 };

    BYTE cbP2PaiData[13] = { 0x11, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x31, 0x32 };

    BYTE cbP3PaiData[13] = { 0x21, 0x21, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x33, 0x33 };

    BYTE cbP4PaiData[13] = { 0x31, 0x31, 0x31, 0x32, 0x33, 0x34, 0x34, 0x35, 0x35, 0x37, 0x37, 0x34, 0x34 };

    //发给玩家的牌

    BYTE cbP1QiPai = 0x01;//起手暗杠

    BYTE cbP2QiPai = 0x31;//杠后起牌东风胡

    BYTE cbP3QiPai = 0x23; 

    BYTE cbP4QiPai = 0x24;

    BYTE cbP5QiPai = 0x25; 

    BYTE cbP6QiPai = 0x26;

    BYTE cbP7QiPai = 0x27;

    BYTE cbP8QiPai = 0x28;

    CopyMemory(&cbCardData[cbLeftCardCount - (MAX_COUNT - 1)], cbP1PaiData, sizeof(cbP1PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 2 * (MAX_COUNT - 1)], cbP2PaiData, sizeof(cbP2PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 3 * (MAX_COUNT - 1)], cbP3PaiData, sizeof(cbP3PaiData));

    CopyMemory(&cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1)], cbP4PaiData, sizeof(cbP4PaiData));

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 1] = cbP1QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 2] = cbP2QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 3] = cbP3QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 4] = cbP4QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 5] = cbP5QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 6] = cbP6QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 7] = cbP6QiPai;

    cbCardData[cbLeftCardCount - 4 * (MAX_COUNT - 1) - 8] = cbP6QiPai;

    }

              玩家在拿到一饼后即可暗杠,摸出东风后胡。

             其它的算法也都可以按同样的路子改出来,注意好牌型和玩家对应关系就可以了。

            好,这节课就讲到这里,咱们下次继续讲”房卡“麻将的开发技巧~

            

      ”房卡“麻将研发技巧,尽在”红孩儿的游戏开发之路“,欢迎关注公众号!

                                                                                          

    转载请注明原文地址: https://ju.6miu.com/read-17923.html

    最新回复(0)