红中麻将自动代打设计

11 篇文章 0 订阅
7 篇文章 2 订阅

        有粉丝问,麻将是否可以实现自动代打的,当然是可以的,只是以前没那么多时间精力去搞,最近相对比较闲,应粉丝要求,我又动手实现了一个麻将的自动代打程序。

先看效果

图片效果是不过瘾的,当然还有视频效果 麻将自动代打算法_桌游棋牌热门视频

        这是一个癞子麻将,比普通麻将要复杂很多,核心算法设计如下:

先将麻将转换成索引:0-8代表万子,9-17代表索子,18-26代表筒子,27-33代表东,南,西,北,中,发,白,所有的索引连在一起是为了方便遍历。

算法组合时,要将癞子抽出来,这样剩下的是非癞子牌进行组合,组合排序时,不够的用癞子补充,穷举所有的组合,最后组合出3x+2这样的公式就是能胡牌了。

       胡牌算法并不难,网上一搜索一大把,难的是如何才能设计打得好,我的的设计思路是:对手上的牌进行打分,如果是单牌,1,9这些就是1分,2,8这些就2分,5,6就3分这样,两个牌的情况11,23,35,这样的就分别是30,20,15,如果是三个牌的组合,就有111,123,456,他们的分数分别是50,30,40。设计好他们的组合分数后,就方便操作了,如果要出一张牌,那么就是尝试去掉每一张牌,这样手上分数组合最高的,证明这张牌应该打出去。碰一张,和杠一张牌也是如此碰牌操作是300分,杠牌操作是350分,如果操作后牌的组合分数大于原来的组合分数,证明是值得去碰牌的,听牌时就选择牌面最多的胡牌张数进行叫牌,红中麻将没有大胡可言,最先胡牌才是王道,当然其他麻将可以根据他的番数来进行酌情选择。麻将算法的智能代打远比扑克简单很多,由于时间有限,视频里面的打法还相对粗糙一点,待我有空,还要将他优化成可以跟人抗衡的自动代打算法,算法的介绍就到这里,至于如何识别,如何操作,前面的跑得快文章都有所介绍,需要你往后翻看。

        有兴趣的可以加私信,相互研究学习,共同进步。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
红中麻将的听牌算法可以分为两个步骤:1.计算所有可能的牌型;2.排除不可能的牌型,得到所有可能的听牌。 Step 1: 计算所有可能的牌型 首先,需要将手牌、已打出的牌和红中牌合并成一个数组,然后对数组进行排序。接着,可以将数组按照顺序分成三个部分:雀头、顺子和刻子。其中,雀头必须是一对相同的牌,顺子必须是三个相邻的牌,刻子必须是三个相同的牌。如果出现了四个相同的牌,那么可以将其拆成一个刻子和一个顺子。 接下来,可以对顺子进行扩展。如果手牌中有相邻的牌可以与顺子形成一个新的顺子,那么就将其合并。这里需要注意的是,如果将顺子和牌型中的其他牌拆开后,可以形成新的顺子或刻子,那么就需要将其加入到牌型中。最后,将所有牌型保存到一个数组中。 Step 2: 排除不可能的牌型,得到所有可能的听牌 在得到所有可能的牌型后,需要对每个牌型进行分析,排除不可能的听牌。具体来说,可以对每个牌型中的每张牌进行分析,看看这张牌是否可以作为雀头或是将来形成一个顺子或刻子。如果不可以,就可以将这张牌作为可能的听牌。 下面是Lua的代码示例: ```lua -- 手牌、已打出的牌和红中牌 local hand = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 19} local discard = {10, 11, 12, 13, 14} local hongzhong = {19} -- 合并数组并排序 local tiles = {} for _, v in ipairs(hand) do table.insert(tiles, v) end for _, v in ipairs(discard) do table.insert(tiles, v) end for _, v in ipairs(hongzhong) do table.insert(tiles, v) end table.sort(tiles) -- 计算牌型 local function calculate_patterns(tiles) local patterns = {} local function dfs(index, jiang) if index > #tiles then table.insert(patterns, jiang) return end for i = index + 1, #tiles do if tiles[i] == tiles[i - 1] then if not jiang and i - index >= 2 then dfs(i + 1, {tiles[i], tiles[i]}) end if jiang and tiles[i] == jiang[1] then dfs(i + 1, jiang) end elseif tiles[i] == tiles[i - 1] + 1 then if jiang and tiles[i] == jiang[1] + 1 then dfs(i + 1, jiang) end if i + 1 <= #tiles and tiles[i + 1] == tiles[i] then dfs(i + 2, jiang) end elseif tiles[i] == tiles[i - 1] + 2 then if i + 1 <= #tiles and tiles[i + 1] == tiles[i] then dfs(i + 2, jiang) end else if not jiang then dfs(i, {tiles[i], tiles[i]}) end end end end dfs(1, nil) return patterns end local patterns = calculate_patterns(tiles) -- 计算听牌 local function calculate_ting(patterns) local ting = {} for _, p in ipairs(patterns) do for i = 1, #p do local t = p[i] if i == 1 or p[i] ~= p[i - 1] then -- 判断是否可以作为雀头 if t == p[i + 1] then goto continue end -- 判断是否可以形成顺子 if t <= 7 and table.indexof(p, t + 1) and table.indexof(p, t + 2) then goto continue end -- 判断是否可以形成刻子 if table.count(p, t) >= 2 then goto continue end -- 可以作为听牌 table.insert(ting, t) end ::continue:: end end return ting end local ting = calculate_ting(patterns) -- 输出结果 print("手牌: ", table.concat(hand, " ")) print("已打出的牌: ", table.concat(discard, " ")) print("红中: ", table.concat(hongzhong, " ")) print("听牌: ", table.concat(ting, " ")) ``` 这段代码首先将手牌、已打出的牌和红中牌合并成一个数组,并对数组进行排序。接着,调用`calculate_patterns`函数计算所有可能的牌型。最后,调用`calculate_ting`函数计算所有可能的听牌。 `calculate_patterns`函数使用深度优先搜索算法计算所有可能的牌型。具体来说,它首先将数组按照顺序分成三个部分:雀头、顺子和刻子。然后,对顺子进行扩展,并将所有牌型保存到一个数组中。 `calculate_ting`函数遍历所有可能的牌型,并对每个牌型进行分析,排除不可能的听牌。具体来说,它对每个牌型中的每张牌进行分析,看看这张牌是否可以作为雀头或是将来形成一个顺子或刻子。如果不可以,就可以将这张牌作为可能的听牌。 最后,输出所有可能的听牌。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值