上篇文章写了斗地主牌型判断的几个简单的牌型的判断,现在来写剩下的几个复杂的牌型
本人小菜鸟,算法写的不好之处请大家不吝赐教
注意下面所有的判断都是先将数字去掉花色之后的判断
--顺子 只要判断相邻的数字数值是否差1就可以
function isConnect(cards)
if not CardUtils.isCards(cards) or 5 > #cards then
return false
end
table.sort(cards)
--2和大小王不能加入顺子
if cards[#cards] > 14 then
return false
end
for i = 1, (#cards - 1) do
if cards[i] ~= cards[i+1] -1 then
return false
end
end
return true
end
-- 连对 33445566 1和2 3和4 5和6 7和8 相等 ,2和3 4和5 6和7 相差1
function isCompany(cards)
if not CardUtils.isCards(cards) or 6 > #cards or (#cards % 2) ==1 then
return false
end
table.sort(cards)
local len = #cards
for i = 1, (len - 1) do
if (i % 2) ==1 then
if cards[i] ~= cards[i + 1] then
return false
end
else
if cards[i] ~= cards[i + 1] - 1 then
return false
end
end
end
return true
end
-- 飞机不带
-- 遍历到三个一组中的第一个的时候判断这组的值是否都相等
-- 遍历到三个一组中的最后一个的时候判断和下一组的数值是不是差一
function isAircraft(cards)
if not CardUtils.isCards(cards) or 6 > #cards or (#cards % 3) ~=0 then
return false
end
table.sort(cards)
local len = #cards
for i = 1, (len - 1) do
if (i % 3) ==1 then
if cards[i] ~= cards[i + 1] or cards[i + 1] ~= cards[i + 2] then
return false
end
elseif (i % 3) == 0 then
if cards[i] ~= cards[i + 1] - 1 then
return false
end
end
end
return true
end
-- 4带2
function isBombTwo(cards)
if not CardUtils.isCards(cards) or 8 < #cards or #cards < 6 or (#cards % 2) ~=0 then
return false
end
table.sort(cards)
local tmpTable1 = {} --存放炸弹牌
local tmpTable2 = {} --存放炸弹带的牌
local tmppos = 0
-- 先从牌中抽出炸弹不带的牌
for pos = 1, (#cards - 3) do
if cards[pos] == cards[pos + 1] and cards[pos] == cards[pos + 2] and cards[pos + 2] == cards[pos + 3] then
table.insert(tmpTable1, cards[pos])
table.insert(tmpTable1, cards[pos + 1])
table.insert(tmpTable1, cards[pos + 2])
table.insert(tmpTable1, cards[pos + 3])
tmppos = pos
end
end
-- 再得到带的牌
for k,v in pairs(cards) do
if v ~= cards[tmppos] then
table.insert(tmpTable2, v)
end
end
if CardUtils.isBomb(tmpTable1) then
if 2 == #tmpTable2 then
return true
elseif 4 == #tmpTable2 then
table.sort(tmpTable2)
if tmpTable2[1] == tmpTable2[2] and tmpTable2[3] == tmpTable2[4] then
return true
end
end
end
return false
end
-- 飞机带翅膀
function isAircraftWing(cards)
if not CardUtils.isCards(cards) or 8 > #cards then
return false
end
if (#cards % 4) ~=0 and (#cards % 5) ~= 0 then
return false
end
-- 先判断有没有炸弹插成三带一的情况如果有那么将其中一个替换为扑克中没有的数(如 19)
table.sort(cards)
local tmp = 0 --记录有几个炸弹 防止有多个炸插成三带一
for k = 1, (#cards - 4) do
if cards[k] == cards[k + 1] and cards[k + 1] == cards[k + 2] and cards[k + 2] == cards[k + 3] then
cards[k + 3] = 19 + tmp
tmp = tmp + 1
end
end
local aircraftCount = math.floor(#cards / 4)
table.sort(cards)
local tmpTable1 = {} --存放飞机的牌
local tmpTable2 = {} --存放飞机带的牌
-- 先从牌中抽出飞机不带
for pos = 1, #cards - 2 do
if cards[pos] == cards[pos + 1] and cards[pos] == cards[pos + 2] then
table.insert(tmpTable1, cards[pos])
table.insert(tmpTable1, cards[pos + 1])
table.insert(tmpTable1, cards[pos + 2])
tmppos = pos
end
end
-- 再得到带的牌
for k1, v1 in pairs(cards) do
local count = 0
for i = 1, aircraftCount do
if v1 == tmpTable1[i * 3] then
count = count + 1
end
end
if count == 0 then
table.insert(tmpTable2, v1)
end
end
if not CardUtils.isAircraft(tmpTable1) then
return false
end
if #tmpTable2 == aircraftCount * 2 then
for i = 1, #tmpTable2, 2 do
if tmpTable2[i] ~= tmpTable2[i + 1] then
return false
end
end
end
return true
end
function getType(postcards)
--如果传递进来的cards没有去掉花色的话就先去掉花色( %100 )再判断
local cards = CardUtils.copyTab(postcards)
for i = 1, #cards do
cards[i] = CardUtils.getValue(cards[i])
end
local len = #cards
if len <= 5 and len > 0 then
if CardUtils.isSingle(cards) then
return SINGLE_CARD
elseif CardUtils.isDouble(cards) then
return DOUBLE_CARD
elseif CardUtils.isBomb(cards) then
return BOMB_CARD
elseif CardUtils.isKingBomb(cards) then
return KINGBOMB_CARD
elseif CardUtils.isThree(cards) then
return THREE_CARD
elseif CardUtils.isThreeOne(cards) then
return THREE_ONE_CARD
elseif CardUtils.isConnect(cards) then
return CONNECT_CARD
elseif CardUtils.isThreeTwo(cards) then
return THREE_TWO_CARD
end
elseif len < 20 and len > 5 then
if CardUtils.isConnect(cards) then
return CONNECT_CARD
elseif CardUtils.isAircraft(cards) then
return AIRCRAFT_CARD
elseif CardUtils.isCompany(cards) then
return COMPANY_CARD
elseif CardUtils.isBombTwo(cards) then
return BOMB_TWO_CARD
elseif CardUtils.isAircraftWing(cards) then
return AIRCRAFT_WING
end
end
return ERROR_CARDS
end