V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
bufannao
V2EX  ›  问与答

请教关于麻将的听牌算法(语言不限,欢迎讨论)

  •  
  •   bufannao · 2014-08-07 17:27:46 +08:00 · 8049 次点击
    这是一个创建于 3553 天前的主题,其中的信息可能已经有所发展或是发生改变。
    简单一些,牌型假设不考虑花色,只包括条、筒、万
    正常手中是13张牌,当再摸一张牌后如何判断是否可以听牌(此时手中是14张牌,需要再打出去一张判断是否能够听牌)?(杠也不可以不考虑)
    胡牌规则不考虑七对子、清一色、大三元、幺、九等等特殊规则,只要简单包括1将牌、1-N刻牌、1-N顺牌即可。
    深知关于这类的算法应该都是商业化的,希望有过研究的不吝赐教。
    25 条回复    2014-08-09 12:44:43 +08:00
    casparchen
        1
    casparchen  
       2014-08-07 18:17:52 +08:00
    我觉得总共才13张牌,遍历所有情况就可以了,难道还要考虑效率么
    yangff
        2
    yangff  
       2014-08-07 18:26:06 +08:00 via Android
    枚举打哪张,搜牌型。
    blacktulip
        3
    blacktulip  
       2014-08-07 18:28:49 +08:00
    这个不需要特殊算法吧,总共才几张牌
    plprapper
        4
    plprapper  
       2014-08-07 18:30:47 +08:00
    这是要靠程序 研究如何出来最合理吗 然后带着程序 杀向麻将馆 。。 哈哈
    bufannao
        5
    bufannao  
    OP
       2014-08-07 19:19:33 +08:00 via Android
    @casparchen
    @blacktulip
    @yangff 看似容易,能上代码么?
    jsonline
        6
    jsonline  
       2014-08-07 19:23:49 +08:00 via Android
    人脑很容易就分辨出来了,何况电脑
    bufannao
        7
    bufannao  
    OP
       2014-08-07 19:47:20 +08:00 via Android
    @jsonline 你试试写个AI,4个电脑玩一把,看看有你想的容易么
    bufannao
        8
    bufannao  
    OP
       2014-08-07 19:51:48 +08:00 via Android
    @plprapper 呵呵,是想写个人机对战,本地玩法
    blacktulip
        9
    blacktulip  
       2014-08-07 20:21:58 +08:00   ❤️ 1
    zjgood
        10
    zjgood  
       2014-08-07 20:26:44 +08:00 via Android
    wo ju ran bu zhi dao ma jiang hai you suan fa shen me de
    bufannao
        11
    bufannao  
    OP
       2014-08-07 20:44:12 +08:00
    @blacktulip 谢谢!
    aheadlead
        12
    aheadlead  
       2014-08-07 21:20:42 +08:00
    A*
    jsonline
        13
    jsonline  
       2014-08-07 21:30:36 +08:00
    AI 和算法不一样吧,我是说判断的算法挺容易的
    casparchen
        14
    casparchen  
       2014-08-07 21:43:49 +08:00   ❤️ 1
    lygmqkl
        15
    lygmqkl  
       2014-08-07 21:56:10 +08:00
    我来出个注意:
    构建9个pools
    A*1 all left
    B*4 4 player's hold
    C*4 4 players's used
    顺序,
    lygmqkl
        16
    lygmqkl  
       2014-08-07 21:59:35 +08:00
    1. A-1
    2. 指针指向4个用户得下一个, 第n个
    3. Bn + 1
    4. 里边n 用户得拍,归类判断是否听牌,胡牌
    5. Bn - 1, Cn + 1
    6, n+1, n+2, n+3 用户分别遍历决定是否有操作,吃,碰,杠,听,胡,方法类似4,计算用户所有得牌
    从1重复,
    难得不是AI的实现,难得是根据剩余牌量+已出牌量推算出,下面的牌的走势,例如是鸡胡还是做大牌。
    Sunyanzi
        17
    Sunyanzi  
       2014-08-07 22:06:29 +08:00   ❤️ 1
    沉迷日麻并曾经可心算番符及得点的人怒答一记 ...

    我当时给自己做过一个练牌的小工具 ... 可以算出切张之后的向听数期待得点以及放铳概率 ...

    当时懒得细写 ... 选择的做法就是穷举 ... 然后比对和牌牌型 ...

    日麻总共一百三十六张牌 ... 共穷举一千八百九十次 ... 算上比对牌型的时间都是一瞬间就完成 ...

    如果要高级一点的算法也可这样 ...

    整理手牌 ... 把所有牌按顺序排列 ... 然后从第一张开始找起 ...

    假如第一张是 4M ... 说明一定没有 2M 和 3M ... 继续检查 ...

    如果存在 4M 或者 5M 继续检查是否存在 4M 或者 6M ... 存在则跳过这三张继续 ...

    如果存在 4M 但不存在第三个 4M 的话放置一个将牌标记继续 ...

    如果存在 6M 的话检查是否存在听牌标记 ...

    如果没有的话跳过这两张并放置一个听牌标记继续 ... 存在的话说明没有听牌直接中止流程 ...

    如果上述条件皆不满足 ... 检查是否存在听牌标记 ...

    如果没有则放置一个听牌标记 ... 如果存在则说明没有听牌直接中止流程 ...

    最后如果有一个或六个将牌标记且有听牌标记说明已经听牌 ...

    如果最后有一个或七个将牌标记且没有听牌标记说明已经和牌 ...

    如果既存在 4M 又存在 4M 4M 5M 和 6M 需要分叉判断 ... 有一次听牌就视为听牌 ...

    描述就是这样 ...

    开发起来较穷举而言比较麻烦 ... 除非是做在线游戏 ... 否则穷举就足够用了 ...

    可能说得有点乱 ... 希望能理解吧 ...
    oIIo
        18
    oIIo  
       2014-08-07 22:23:40 +08:00
    你应该不是单纯的指听牌吧? ai的话肯定还要分析桌面的牌。 单纯的判断是否可以听牌,按照楼上们说的直接穷举就行了,先把将牌提出来,判断是否听将牌,然后3个3个的配。
    oIIo
        19
    oIIo  
       2014-08-07 22:29:12 +08:00
    ai 打牌的话,就麻烦了,我之前做过一个字牌的游戏(和麻将类似也是3个一组还有杠、将,但是有21张牌),ai打牌的话用穷举分支太多(算出较优解得1、2秒),必须根据打牌经验剪枝。
    bufannao
        20
    bufannao  
    OP
       2014-08-07 22:43:23 +08:00
    @Sunyanzi 后面的算法看懂了,前面说的穷举没明白,一千八百九十次是怎么来的?还有比对牌型是指什么?
    Sunyanzi
        21
    Sunyanzi  
       2014-08-07 22:53:44 +08:00
    @bufannao 我自己看了一遍也发现问题了 orz ... 是四百六十二次 ... 不是一千多次 ...

    对比牌型是指确认手上的牌是否和了 ... 穷举的过程是这样 ...

    第一次先确认起手牌是不是和了 ... 没和的话从十四个位置的每一个位置把所有牌穷举一遍 ...

    如果可以通过替换某一张牌为另一张牌和牌的话 ... 说明打掉那张牌就可以上听 ...

    总穷举次数为 ( 34 - 1 ) * 14 ... 麻将牌总共三十四种牌 ... 手上有十四张 ... 减一是减掉起始那张 ...
    bufannao
        22
    bufannao  
    OP
       2014-08-07 23:15:17 +08:00
    @Sunyanzi 谢谢,懂了!另外之前说的『如果存在 6M 的话检查是否存在听牌标记 ... 』是否应该是『如果存在 5M 但不存在 6M 的话检查是否存在听牌标记 ... 』
    Sunyanzi
        23
    Sunyanzi  
       2014-08-07 23:43:21 +08:00
    @bufannao 那个情况是如果存在 4M 不存在 5M 但存在 6M 的话 ... 检查听牌标记 ...

    4M 6M 是听牌 ... 若之后的牌被完整跳过且将牌标记出现一次说明这个牌和单张 5M ...

    另外的情况是得到超过一个将牌标记或者中途中止 ... 这都是未听牌 ...

    至于 5M 6M 的话 ... 那就等于 4M 5M 的情况了 ... 我在上面有详述 ...
    zhujinliang
        24
    zhujinliang  
       2014-08-08 00:06:03 +08:00 via iPad
    先完成和牌算法: 先尝试分成4个组及一个雀头的形式,如不能成立,则为不和了,此步骤可过滤大部分情况。之后可能有多种分法,需对每种分法套用排型比较,依次统计得点,取得点最高的分法

    实现和牌算法后,穷举每个牌,作为自摸牌,如果可和,则为听牌
    aheadlead
        25
    aheadlead  
       2014-08-09 12:44:43 +08:00
    空听立直什么的....
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5297 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:31 · PVG 17:31 · LAX 02:31 · JFK 05:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.