麻将胡牌算法
运用递归思路,先找出两张一样的牌作将牌,然后在剩下的牌中找顺子和三个一样的牌,当剩余的牌数为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