棋牌游戏算法——字牌系列总结

字牌介绍

       字牌的基本介绍我就不多说了,可以自行百度。大字牌_百度百科 

       我这里想给字牌做个归类。我做过很多款字牌,例如: 四川的“贰柒拾”、湖南的 “宁乡跑胡子”,“湘潭跑胡子”,“沅江鬼胡子”,“益阳歪胡子”、广西的“八一字牌”,“桂林字牌”,“全州字牌【四个癞子】”,“飞飞字牌【一个癞子】”等

       虽然有这么多玩法,但是其核心的流程都是大同小异的,我所讲的核心流程是指,吃牌,比牌,碰牌,偎(啸),跑(提,龙),胡(王胡)等操作,这种基本操作在各个字牌中都差不多,只不过叫法和表现形式不一样而已。

但对于番型,算分等就有很大的区别,当然还有一些细节方面的差异,比如有的需“挡底”,“翻神”,“翻醒”,“八块”等,或者一些不同的地方性规定。我个人根据玩法的相似性和开发难度给大家进行一下归类。

1、贰柒拾系列:基本都是四川体系,如:"乐山三人",“十四张三人”,“犍为三人”等,后面又在这些玩法上继续扩展,衍生出二人,四人等玩法,这种字牌按圈对局,雨分计算相对复杂,最优解要与圈牌番型相结合。   玩法难度:★★★★     

2、跑胡子系列:这个系列的衍生玩法最多,是大家最常玩的一套规则体系,如:“宁乡跑胡子”,“湘潭跑胡子”,“常德扯胡子” ,以及广西的一些字牌,这种系列主要有比较多的系统操作,难点在于各种按钮操作和系统操作的优先级处理上。 玩法难度:★★★

3、鬼胡子系列:这个系列主要是湖南几个地方在玩,沅江,益阳等地,其不同于跑胡子系列的点在于胡牌规则完全不同(不是按胡息的),还有一些牌型的组合最优解(四张可以拆出来组合),番型也特别的多。  玩法难度:★★★★

跑胡子系列的基础逻辑相对于其他两个系列要简单一点,但对于带癞子的,其难度就完全提升了一个档次。

例如广西的全州字牌,有四个癞子,其胡法还支持“王闯,王炸,王钓”,就是所谓的胡任意一张的那种,并需要配合翻醒找到其最优解,其逻辑和难度成指数上升。

        我自己开发了一款APP,里面包括了下面所有的字牌玩法,欢迎私信我,学习交流~

展示一些牌局中的截图给大家瞧瞧:分别是牌局中和小结算,截图来源于部分棋牌APP。

乐山贰柒拾:

沅江鬼胡子:

全州字牌(带癞子):

桂林字牌:

字牌算法:

  之前本人写过一篇关于字牌“贰柒拾”的介绍,里面有一部分关于胡牌算法的介绍。链接:棋牌算法——“贰柒拾”(字牌)_Snovi-的博客-CSDN博客

写的算是比较简单,因为当时我对字牌还处于一个初识的状态,经过了这两年的磨练,做了这么多款字牌,经过了很多种尝试,彻底对字牌的算法有一个深刻的理解,下面给大家详细介绍一下字牌的胡牌算法。

字牌采用一种叫“回溯法”的算法来计算胡牌。而对于带癞子的情况,可以采用“多路回溯法”

问题一:什么是回溯法? 

答:回溯法实际上属于一种递归算法,就是用一套相同的逻辑,基于不同的数据状态进行计算,设定一个条件(这里可以是胡息数),一旦条件成立,就跳出当前回溯过程。

问题二:为什么要用回溯法? 

答:回溯法虽然在计算性能上有不稳定的地方,肯定是比不上麻将的查表法的,但是没办法,字牌的胡牌组合太过于复杂,目前我认为很难构造胡牌表来匹配,即使可以,也会占用大量内存。

其实在字牌的计算中,存在一个最优解的情况,而用回溯法反而能够在计算中得到最优结果,所以在性能计算问题是完全没有问题的,甚至更快。而且更关键的一点,回溯法是可以拆分的,即可以形成多路(多线程)回溯,

特别是有癞子的情况下,多路回溯法的性能可能不亚于查表法。

问题三:回溯法怎么用?

答:往下翻

字牌胡牌算法“回溯法”介绍 

图示:思维流程图

         

单路回溯法:力求只用一次串行回溯,通过牌型的计算,直接求出一个最优结果,因为单路回溯法只进行一次计算,所以对计算的方案有比较高的要求,一般按照大牌型优先于小牌型的逻辑计算(胡息),但一旦涉及到胡息番型混合组合取最优解的情况,

这种单次回溯就显的比较吃力。如果这种情况很少的话,可以通过构造两个数据包,进行两次(多次)单路回溯,然后比较结果,这是一种"伪多路"(单线程),但在实际操作计算中确实很有效果,即保留的单路回溯的效率与清晰,又能减少大量的比较计算。

基本上只要不带癞子的都可以才用单路回溯法,其中“贰柒拾”和“鬼胡子”系列对计算思维要求要高一点。当然也可以把单路回溯强行拆成多路回溯,但个人觉得没有必要。

多路回溯法:通过同时进行多次回溯,分别计算出结果,最终得到满足条件的结果集。注意,多路回溯不是指同时进行多个“单路回溯”,(不是意味着开多个线程,每个线程跑一次单路回溯,这种是叫多线程版“伪多路”),真正的多路回溯的精髓在于,

每一次数据包的计算都是无状态的,只关心数据包自己的计算过程,并不关心数据包来自哪一路或来自哪一次。举个例子:现在有一张牌可以胡十种结果,每一种结果需要计算十次,总共有一百个数据包,多路回溯的优势在于每次可以同时计算多个数据包,

而不用关心当前数据包的状态(多线程同时进行),直到所有数据包计算完成,获得结果集,再计算最优解。

值得一提的是,单路回溯原则上是单线程的,所以要注意计算量,如果计算过于复杂或者最优解无法通过一次计算得出,则不适用单路回溯。多路回溯需要配合多线程将计算性能发挥到最优,以满足计算出所有结果的需要,多路回溯需要设定一个最长计算时间,因为需要等待多有路子里的数据包都计算完,这就涉及到线程互相等待机制了,建议采用乐观锁机制。

“回溯法”计算逻辑介绍

       不管你的回溯法用的多好,不管你是单线程还是多线程,都离不开中间的计算过程,计算写的好不好,会严重影响回溯法的性能,好的计算过程能够在最快的时间内得出最优解(单路回溯法),全面的计算逻辑才能找出所有满足胡牌组合的情况。

字牌中的胡牌计算,无非就是计算手牌,将手牌组合成不同的组合,当把所有手牌都组合完,判断是否满足胡牌条件并结束计算。下面讲详细的介绍回溯法中的“计算”逻辑。 

计算过程流程图:

分步骤说明:

①:手牌进行排序,一般按从大字到小字这样排(这里的手牌,可能包含最后胡的那张牌,也有可能不包含,要根据情况而定,不一定是21张,已经吃碰杠的牌也不能算,但要累加胡息)

②:取出第一张,判断一下手牌里存在多少张,根据张数不同可能完成的组合也不同,注意,这里要考虑到一种情况,就是这张牌刚好是胡的那张牌,这样会增加很多限制

③:依次尝试所有相应的组合,就拿吃来说,就先去组2710,因为2710有胡息,如果组合成功,就可以直接进行下一个回溯,这样就是最优解优先原则,2710不行再考虑其他组合

④:组合成功后,要根据组合的类型进行当前数据包状态的修改,比如加胡息,拼牌型,记录所有需要用来判断胡牌的条件信息,并移除掉相应的牌,递归进行下次回溯计算

⑤:当所有手牌都组合完成时(如果其中有不能组合的就不会到这一步),判断胡牌条件,如果条件成立,退出计算,得到胡牌结果。

PS:这样的步骤一般用于跑胡子系列,而对于鬼胡子(四张可拆),带癞子的(无法优先最优解),则要更加复杂一点,但整一个的逻辑思路还是一样滴。

代码(JAVA):

这篇文章较为理论,实际上涉及的代码有很多,其中带癞子的更涉及到多线程相互等待的操作。

贴了不全也只是一个思路,有需要的评论区吧。

贴上最为核心的方法而且呈上齐下的一个方法。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
C++棋牌游戏服务器架构通常包括以下几个主要组件: 1. 游戏逻辑层:负责处理游戏规则、游戏状态的更新和管理,以及处理玩家的操作请求。这一层通常由C++编写,包括游戏逻辑的实现和相关算法。 2. 网络通信层:负责处理客户端和服务器之间的网络通信。这一层通常使用TCP或UDP协议进行数据传输,并提供网络连接的建立、断开、数据收发等功能。常用的C++网络库有Boost.Asio、libevent等。 3. 数据库层:负责存储和管理游戏数据,如玩家信息、游戏记录等。这一层通常使用关系型数据库(如MySQL)或NoSQL数据库(如Redis)来存储数据,并提供相应的读写接口。 4. 多线程/多进程管理:为了提高服务器的并发处理能力,可以采用多线程或多进程的方式来处理客户端请求。多线程可以使用C++标准库中的std::thread或第三方库如pthread来实现,多进程可以使用fork或者第三方库如boost.process来实现。 5. 负载均衡与高可用性:为了提高服务器的性能和可用性,可以采用负载均衡技术将客户端请求分发到多台服务器上进行处理,同时可以使用集群和备份机制来实现高可用性。常用的负载均衡软件有Nginx、HAProxy等。 6. 安全认证与防作弊:为了保证游戏的公平性和安全性,可以在服务器端进行安全认证和防作弊处理。常见的技术包括数据加密、防止外挂和作弊程序的检测与防御等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Snovi-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值