記錄一下學習筆記和看到值得記錄的文章
阿新 • • 發佈:2019-02-10
上篇文章寫了鬥地主牌型判斷的幾個簡單的牌型的判斷,現在來寫剩下的幾個複雜的牌型
本人小菜鳥,演算法寫的不好之處請大家不吝賜教
注意下面所有的判斷都是先將數字去掉花色之後的判斷
--順子 只要判斷相鄰的數字數值是否差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