麻将胡牌递归算法(lua)

麻将胡牌算法

运用递归思路,先找出两张一样的牌作将牌,然后在剩下的牌中找顺子和三个一样的牌,当剩余的牌数为0,则排定可以胡牌。目前只是四川麻将的赢牌番型,除去风牌的。可自行进行扩展。(万:11-19,筒:21-29,条31-39),直接可以下载使用。

mjwintable类:


--赢牌倍率
gMJWinRate = { 1, 2, 4, 4, 4, 4, 8, 8, 8, 16, 16, 16, 16, 32, 64, 256 }
gMJWinFJRate = { 2, 2 }

--赢牌基本类型
gMJWinType = { }
--翻1倍
gMJWinType.ordinary                      = 1                        --平胡
--翻2倍
gMJWinType.duiduiHu                      = 2                        --对对胡

--翻4倍               
gMJWinType.ordinaryQ                     = 3                        --清一色             
gMJWinType.yaojiu                        = 4                        --幺九
gMJWinType.sevendui                      = 5                        --七小对
gMJWinType.jingou                        = 6                        --金钩钓 

--翻8倍           
gMJWinType.duiduiHuQ                     = 7                        --对对胡清一色
gMJWinType.duiduiHu258                   = 8                       --对对胡258
gMJWinType.sevenduiQ                     = 9                       --清七小对

--翻16倍
gMJWinType.yaojiuQ                       = 10                       --幺九清一色
gMJWinType.sevenduiL                     = 11                       --龙七小对
gMJWinType.jingouQ                       = 12                       --清金钩钓
gMJWinType.jingou258                     = 13                       --金钩钓258

--翻32倍
gMJWinType.sevenduiQL                    = 14                       --清龙七小对
--翻64倍
gMJWinType.arhat                         = 15                       --十八罗汉
--翻256倍
gMJWinType.arhatQ                        = 16                       --清十八罗汉

--赢牌附加类型
gMJWinFJType = { }
gMJWinFJType.noyaojiu                      = 1                        --断幺九
gMJWinFJType.doorclear                     = 2                        --门前清

--外部调用方法
--匹配牌型(1--总牌,2--手牌,3--杠数)
--paislist所有牌table包括手牌、碰牌、杠牌(去掉一张按三张算)如:paislist = {11,12,13,14,15,33,21}
--handpaisList手牌table 如:handpaisList = {11,12,13,14,15,33,21}
--gangPengList杠碰牌table
--gangNum杠个数
function CheckMJWinTable( paislist, handpaisList, gangPengList, gangNum )
	if #paislist ~= 14 then
		do return end
	end
	
	table.sort( paislist, function( a, b )
			return a < b
		end)
		
	table.sort( handpaisList, function( a, b )
			return a < b
		end)
	
	local isWin = false	
	local winType = nil		
	local sameColour   		= TableBySameColour(paislist)
	if gangNum == 4 then	-- 判断十八罗汉
		if handpaisList[ 1 ] == handpaisList[ 2 ] then
			local paiType	= math.floor( handpaisList[ 1 ] / 10 )
			for pai, v in pairs( gangPengList ) do
				if math.floor( pai / 10 ) ~= paiType then
					winType	= gMJWinType.arhat
					do return true, winType end
				end
			end
			
			winType	= gMJWinType.arhatQ
			do return true, winType end
		end
	else
		local win, duiLong = MJWinTableBySevenDouble( handpaisList )
		if win == true then -- 判断七对
			if sameColour == true then
				if duiLong == true then
					winType	= gMJWinType.sevenduiQL
				else
					winType	= gMJWinType.sevenduiQ
				end
			else
				if duiLong == true then
					winType	= gMJWinType.sevenduiL
				else
					winType	= gMJWinType.sevendui
				end
			end
			
			do return win, winType end
		elseif MJWinTableByCommon( handpaisList ) then
			local duiWin 	= TableByDuiDuiHu( handpaisList, gangPengList, gangNum )
			local win19 	= MJWinTableByCommon( handpaisList, gangPengList, 19 )
			local win258 	= MJWinTableByCommon( handpaisList, gangPengList, 258 )
			local jingouWin	= #handpaisList == 2			
			if jingouWin == true and ( win258 == true or sameColour == true ) then
				if win258 == true then
					winType	= gMJWinType.jingou258
				else
					winType	= gMJWinType.jingouQ
				end
				do return true, winType end
			elseif win19 == true and sameColour == true then	-- 青19
				winType	= gMJWinType.yaojiuQ
				do return true, winType end
			elseif duiWin == true and ( win258 == true or sameColour == true ) then
				if win258 == true then
					winType	= gMJWinType.duiduiHu258
				else
					winType	= gMJWinType.duiduiHuQ
				end
				do return true, winType end
			elseif sameColour == true or win19 == true or jingouWin == true then
				if sameColour == true then
					winType	= gMJWinType.ordinaryQ
				elseif win19 == true then
					winType	= gMJWinType.yaojiu
				else
					winType	= gMJWinType.jingou
				end
				
				do return true, winType end
			elseif duiWin == true then
				winType	= gMJWinType.duiduiHu
				do return true, winType end			
			else
				winType	= gMJWinType.ordinary
				do return true, winType end
			end
		end
	end
	
	return false
end

--检测附加翻型(在胡牌的基础上判断)参数1--断幺九,参数2--门清
function CheckMJFJType( paislist, handpaisList )	
	local isDuanYaoJiu	= false
	local isMenQing		= false
	local paiNum = 0	
	for index, pai in pairs( paislist ) do
		if pai % 10 ~= 9 and pai % 10 ~= 1 then		
			paiNum = paiNum + 1
		end		
	end
	if paiNum == 14 then
		isDuanYaoJiu = true
	end
	if #handpaisList == 14 then		
		isMenQing = true	
	end
	return i
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值