棋牌麻将 - 无癞子胡牌算法(优化)
2017-11-30 17:34
281 查看
基础知识
本文涉及的所有名词均在博文中有说明: http://blog.csdn.net/kunyus/article/details/78644517核心思想
去伪存真: 满足胡牌的部分, 要么是 {3*n}(不带将), 要么是 {3*n+2}(带将).端本正源: 麻将牌胡牌(除特殊规则)和牌面没有直接关系, 只和数量以及所处位置(顺子)相关.
去粗取精: 麻将牌所有组合中, 只有顺子和其他牌有关联关系,且关系只存在于相连的两张牌中.
完整处理流程
生成中间表
将序数牌按花色以及牌个数进行归表并记录表中牌的总个数.此处用万举例, 其他花色结果一样:
手牌 万: 1-9 各一张, 此时表内容应为: 111111111(9)
手牌 万: 11 22 333 4 5 6 77 88, 此时表内容应为: 2231112200(14)
将字牌按牌个数进行归表并记录表中牌的总个数, 相邻牌用 0 隔开.
如: 东风 南风 西风 北风 红中 发财 白板, 表内容: 1010101010101(7)
任意表中牌个数出现不满足 {3*n} 且不满足 {3*n+2} 的, 直接判定无法胡牌.
type MTable struct { Count int Tiles []int } // 0x01 - 0x09 - 筒 // 0x11 - 0x19 - 万 // 0x21 - 0x29 - 条 // 0x31 0x33 0x35 - 中发白 // 0x41 0x43 0x45 0x47 - 东南西北 func compileTiles(unlockTiles []byte) (int, error) { mtables := make([]MTable, 7) for i, _ := range mtables { mtables[i].Tiles = make([]int, 9) } for _, tile := range unlockTiles { group := tile / 0x10 if int(group+1) > len(mtables) { return 0, errors.New("unrecognized type " + strconv.Itoa(int(group)) + " of tile") } tile := tile % 0x10 - 1 if int(tile) > (len(mtables[group].Tiles) - 1) { return 0, errors.New("unrecognized tile " + strconv.Itoa(int(tile))) } mtables[group].Count++ mtables[group].Tiles[tile]++ if mtables[group].Tiles[tile] > 4 { return 0, errors.New("abnormal number " + strconv.Itoa(mtables[group].Tiles[tile]) + " of tile " + strconv.Itoa(int(tile))) } } super := 0 for _, slice := range mtables { if 0 == slice.Count{ continue } rest := slice.Count % 3 if 0 != rest && 2 != rest { return 0, errors.New("slice length " + strconv.Itoa(int(slice.Count)) + " check does not pass") } if err := decomposeMTable(slice.Tiles); nil != err{ return 0, err } } return super, nil }
处理中间表
分别对生成的中间表进行正向遍历, 并分别进行 2 - 6 步处理.当前位是否为 0, 为 0 直接跳到下一个继续处理.
当前值是否为 1 且表长度大于 3, 满足分别对当前值和后两个值减 1 , 出现负数无法胡牌.
当前位是否为 2, 满足将其视为刻子, 值改 0, 跳到下一个继续处理
当前位是否为 3 , 满足将值改为 1 跳到步骤 2 处理, 处理失败无法胡牌.
当前位是否为 4, 满足将值改为 1 跳到步骤 2 处理, 处理失败将值改为 1 跳到步骤 2 处理, 处理失败无法胡牌.
func decomposeMTable(slice []int) (error){ sliceSize := len(slice) for index := 0; index < sliceSize; index++ { tileCount := slice[index] switch(tileCount){ case 0: continue case 1: if (sliceSize - index) < 3 { return errors.New("failed to remove sequence, slice length is not enough") } for k := 0; k < 3; k++{ if slice[index + k] < 1 { return errors.New("failed to remove sequence, continuous tile does not exist") } slice[index + k]-- } case 2: slice[index] = 0 default: // 3 && 4 slice[index] -= 2 for ; slice[index] > 0; slice[index]--{ tslice := make([]int,len(slice) - index) copy(tslice, slice[index:]) if err := decomposeMTable(tslice); nil == err{ return nil } } if 4 == tileCount { return errors.New("there can not be four identical tiles") } slice[index] = 0 } if 0 != slice[index]{ return errors.New("unexpected error") } } return nil }
相关文章推荐
- 棋牌麻将 - 无癞子胡牌算法(第三版)
- 棋牌麻将 - 无癞子胡牌算法
- 麻将的胡牌算法
- 山东手机房卡类棋牌游戏开发微信登录麻将APP地方特色版定制
- 工作中棋牌麻将的总结一些术语(2)
- 常玩山东手机棋牌麻将会有你想不到的延年益寿功效开发好的棋牌更是重要
- 麻将简单胡牌算法
- 幼麟棋牌技术分享系列:H5棋牌游戏加载速度优化
- 麻将的胡牌算法
- 【网狐荣耀修改教程】第三篇、去除红中麻将的癞子规则
- Java实现的麻将胡牌算法
- 网狐棋牌 麻将分析
- 棋牌麻将 - 基础名词讲解与汇总
- 网狐棋牌 麻将服务器配置
- 麻将的胡牌算法
- 检测四川麻将是否胡牌算法的实现
- 棋牌游戏定制开发 H5游戏开发 麻将游戏定制 手游棋牌游戏开发
- 吉林手机棋牌和手机麻将开发公司做的最好的是哪一家公司-青岛狼人
- 临沂手机电玩城|手机麻将游戏开发|棋牌APP定制|齐鲁约牌吧加盟
- 棋牌麻将 - 常用胡牌规则解释及汇总