300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 简单的麻将和牌算法(以卡五星为例)

简单的麻将和牌算法(以卡五星为例)

时间:2021-07-10 14:24:01

相关推荐

简单的麻将和牌算法(以卡五星为例)

介绍

之前为了写这个程序, 在CSDN等平台上搜索过一些算法, 但是都不太满意, 因此自己手搓了一个. 这个算法也很容易应用到各种其他规则上.

前置内容

(这里默认读者会打日麻或者国标)

卡五星只有3种牌: 三元牌(字牌), 饼子, 条子. 总计21种.

🀐🀑🀒🀓🀔🀕🀖🀗🀘

🀙🀚🀛🀜🀝🀞🀟🀠🀡

🀆🀅🀄

不能吃.

和牌类型比较简单, 除了七对以外全都是基础牌型.

算法解释

数据的表示方法

我把手牌和副露分别表示为长21的列表, 每个元素表示对应的某种牌的数量. 代码中传入参数为手牌和副露之和, 长度为42.

胡牌的判断

先找出数目大于等于2的牌(即可以做将的牌). 若满足七对的情况则可胡牌, 对子数不足1则不可和牌. 否则分别遍历每个对子的情况, 遍历时去除这一对, 从剩余的12张牌里依序遍历, 找出刻和顺, 其数目加副露数若为4则和牌. 不足4则无法和牌.

听牌的判断

听牌和胡牌的判断方式基本一致.

可胡时, 手牌有14张(杠和碰都记为3张). 听牌时, 手牌有13张. 判断听哪张牌, 可以遍历所有种类的牌, 分别判断往手牌中添加一张该种牌后是否胡牌.

代码实现(Python)

和牌

def isWin(col: list[int]) -> bool:checkTileCount(col, 14)tei = [] #不会出现重复的teisu = 0for i in range(21):if col[i] >= 2:tei.append(i)teisu += 1if col[i] == 4:teisu += 1if teisu == 0: return Falseif teisu == 7: return Truefulu = 0for i in range(TYPE, 2 * TYPE):fulu += col[i] != 0if teisu == 1 and fulu == 4: return Truefor i in tei:col2 = col[0:TYPE].copy()col2[i] -= 2khe = 0sun = 0for col3 in [col2[0:9], col2[9:18], col2[18:21]]:for j in range(len(col3)):if col3[j] >= 3:col3[j] -= 3khe += 1if j + 2 >= len(col3) or len(col3) != 9:continue#顺子while col3[j] > 0 and col3[j + 1] > 0 and col3[j + 2] > 0:col3[j] -= 1col3[j + 1] -= 1col3[j + 2] -= 1sun += 1if khe + sun + fulu == 4:return Truereturn False

听牌

def tinpai(col: list[int]) -> list[int]:checkTileCount(col, 13)return [i for i in range(TYPE) if canHu(col, i)]def tinpai_dict(col: list[int], paiho: list[int]) -> dict[int:int]:r = {}for i in tinpai(col):r[i] = 4 - paiho[i]return rdef tinpai_count(col: list[int], paiho: list[int]) -> int:return sum([4 - paiho[i] for i in tinpai(col)])# 打哪张牌听牌? 输出: 打的牌序号->听哪些牌def tinpai14(col: list[int]) -> dict[int:list[int]]:checkTileCount(col, 14)r = {}for i in range(TYPE):if col[i] == 0:continue_col = col.copy()_col[i] -= 1tin = tinpai(_col)if len(tin):r[i] = tinreturn r

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。