前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >麻将游戏的听牌算法

麻将游戏的听牌算法

作者头像
李海彬
发布2018-03-23 11:11:17
2.5K0
发布2018-03-23 11:11:17
举报
文章被收录于专栏:Golang语言社区Golang语言社区

测试测试!!~~~~这两周都是在测试各种BUG,没事情的时候自己在网上学学新知识,也为下个月的游戏改版预热。最近呢我也开始了我的shader之旅,估计也是这充满神秘和艰辛的旅途吧,哈哈哈! 今天写的这篇文章是为下次项目添加的一个功能,也就是麻将的听牌功能。不打麻将的童靴一定不知道什么叫听牌,可是我打麻将最初也不知道什么是听牌,霍霍,好丢人啊,估计是以前有东南西北中发白的时候这种功能多一些,现在都是血战麻将了。我自己说不清就请度娘吧,听牌:麻将游戏术语,牌局之中,到达了「只要再凑一张即可成功胡牌」的阶段,就叫「听牌」,也就是说你目前的手牌有叫,然后听牌就可以快速知道你可以胡什么牌。 好了,那么我们就说一说具体的实现方式吧!要知道麻将是由108张牌组成,其中花色分为了万、筒、条三种,每种花色有1~9的数值。麻将的胡牌方式我在这里就不再解释了,有兴趣的可以百度一下。我们使用一个数组来存储一副牌:

代码语言:javascript
复制
int[] midList = new int[30] {  0,      
                               0,0,0,0,0,0,0,0,0,            //        1万~9万的个数     
                               0,      
                               0,0,0,0,0,0,0,0,0,          //         1筒~9筒的个数     
                               0,      
                               0,0,0,0,0,0,0,0,0          //        1条~9条的个数                                        
                               };</span>  

这里就是建立了一个长度为30的数组,从下标1开始存储麻将的个数,其中下标1~9代表的就是1万~9万,下标11~19代表的就是1筒~9筒,下标21~29代表的就是1条~9条。这样,一副手牌的就能完整的很直观的反应出来。除去金勾掉和小七对的牌型,我们的胡牌基本就可以定为:XX XXX XXX XXX XXX 其中XX代表的将牌,XXX则是代表三张相同牌或者顺子。明白了胡牌方式以后,我们就可以开始我们的听牌。如果要听牌,就要算出所有的可能胡的牌,那牌有108张,我们不可能都听完吧?!那效率得多低。当然是不用了啦,首先我们要知道自己缺什么牌,比如我们缺筒,那么我们就不需要考虑筒的情况,也不需要考虑10,20,30的情况,因为这里不存数据默认为0的。经过剔除以后,我们的查找就减少了很多。接下来看看代码:

代码语言:javascript
复制
<span style="font-size:18px;">public bool mayHu(int[] pai)  
    {  
 if (remainPai(pai))  
        {  
            jiangPai = 0;  
 return true;  
        }  
 for (int i = 1; i < 30; i++)  
        {  
 
 if (pai[i] <= 0 || (i > playerService[0].player.queZhang && i < playerService[0].player.queZhang + 10)|| (i%10==0))  
            {  
 continue;  
            }  
 if (pai[i] == 4)  
            {  
                pai[i] = 0;  
 if (mayHu(pai))  
                {  
 return true;  
                }  
                pai[i] = 4;  
            }  
 if (pai[i] >= 3)  
            {  
                pai[i] -= 3;  
 if (mayHu(pai))  
                {  
 return true;  
                }  
                pai[i] += 3;  
            }  
 if (jiangPai == 0 && pai[i] >= 2)  
            {  
                jiangPai = 1;  
                pai[i] -= 2;  
 if (mayHu(pai))  
                {  
 return true;  
                }  
                jiangPai = 0;  
                pai[i] += 2;  
            }  
 if (i % 10 != 8 && i % 10 != 9 && pai[i + 1] > 0 && pai[i + 2] > 0)  
            {  
                pai[i]--;  
                pai[i + 1]--;  
                pai[i + 2]--;  
 if (mayHu(pai))  
                {  
 return true;  
                }  
                pai[i]++;  
                pai[i + 1]++;  
                pai[i + 2]++;  
            }  
 
        }  
 return false;  
    }  
 public bool remainPai(int[] pai)  
    {  
 int sum = 0;  
 for (int i = 0; i < pai.Length; i++)  
        {  
            sum += pai[i];  
        }  
 if (sum == 0)  
        {  
 return true;  
        }  
 return false;  
 
    }</span>  

上面的代码就是听牌的主要代码。使用了递归算法来处理这个问题代码看起来也简单了很多。上面主要的思路我简单解释一下:首先我们要从判断14张手牌是否有叫,需要分别剔除4张相同牌,3张相同牌,然后就是对子,最后就是顺子。我们利用递归来分别处理每一种可能的情况,如果此次递归结束后剩余牌为0,则代表这张是我们的胡牌了。

这里给出的只是主要算法,需要的童鞋可以下载自行更改测试一下。有什么问题或者错误欢迎提出来或者给我留言哦。谢谢大家!!!!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档