|
- --[[
- 3~KA2(从小到大)
- tip: 假设有个梅花3, 具体牌值则是为1,标准牌值是0x11
- ]]
-
- local defs = require("pk_erdoudizhu.luaScript.Def_ERDouDiZhu")
- local PokerUtil = class("PokerUtil")
-
- -- 值
- local Value_2 = 0x0d -- 2的具体牌值
- local Value_Joker_Little = 0x0e -- 小鬼的具体牌值
- local Value_Joker_Big = 0x0f -- 大鬼的具体牌值
-
- -- 从小到大排序
- function PokerUtil.sortOrder(a, b)
- return a < b
- end
-
- -- 从大到小排序
- function PokerUtil.sortDesc(a, b)
- return a > b
- end
-
- -- 从小到大排序(根据扑克值) v指value, t指type
- function PokerUtil.sortOrder_By_PokerValue(a, b)
- local v_a = PokerUtil:getCardValue(a)
- local v_b = PokerUtil:getCardValue(b)
- if v_a ~= v_b then
- return v_a < v_b
- else
- local t_a = PokerUtil:getCardType(a)
- local t_b = PokerUtil:getCardType(b)
- return t_a < t_b
- end
- end
-
- function PokerUtil:ctor(param)
- self:initFunction()
- end
-
- -- 获得牌类型 0方块 1梅花 2红桃 3黑桃
- function PokerUtil:getCardType(card)
- return toint(getNumBand(card, 0xf0) / 0x0f)
- end
-
- -- 获得牌的具体牌值
- function PokerUtil:getCardValue(card)
- return getNumBand(card, 0x0f)
- end
-
- function PokerUtil:initFunction()
- self:initTypeMap()
- -- self:initTipMap()
- end
-
- -- 定义数组,key是手牌的长度,value则是可能组成长度为key的牌型判断方法
- function PokerUtil:initTypeMap()
- for i = 1, PokerUtil.Card_Max_Length do
- PokerUtil.Card_Type_Map[i] = {}
- end
-
- -- 单张
- table.insert(PokerUtil.Card_Type_Map[1], self.isSingle)
-
- -- 对子
- table.insert(PokerUtil.Card_Type_Map[2], self.isDouble)
-
- -- 三张
- table.insert(PokerUtil.Card_Type_Map[3], self.isThree)
-
- -- 顺子
- for i = PokerUtil.Less_Line, PokerUtil.Max_Line do
- table.insert(PokerUtil.Card_Type_Map[i], self.isLine)
- end
-
- -- 连对
- for i = PokerUtil.Less_Lian_Dui, PokerUtil.Card_Max_Length do
- if i % 2 == 0 then
- table.insert(PokerUtil.Card_Type_Map[i], self.isDoubleLine)
- end
- end
-
- -- 三带一
- table.insert(PokerUtil.Card_Type_Map[4], self.isThreeTakeOne)
-
- -- 三带二
- table.insert(PokerUtil.Card_Type_Map[5], self.isThreeTakeTwo)
-
- -- 四带一张
- table.insert(PokerUtil.Card_Type_Map[5], self.isFourTakeOneSinle)
-
- -- 四带一对
- table.insert(PokerUtil.Card_Type_Map[6], self.isFourTakeOneDouble)
-
- -- 四带二张单排
- table.insert(PokerUtil.Card_Type_Map[6], self.isFourTakeTwoSinle)
-
- -- 四带二对子
- table.insert(PokerUtil.Card_Type_Map[8], self.isFourTakeTwoDouble)
-
- -- 飞机不带
- for i = PokerUtil.Less_Plane, PokerUtil.Card_Max_Length do
- if i % 3 == 0 then
- table.insert(PokerUtil.Card_Type_Map[i], self.isPlaneNoTake)
- end
- end
-
- -- 飞机带单
- for i = PokerUtil.Less_Plane + 2, PokerUtil.Card_Max_Length do
- if i % 4 == 0 then
- table.insert(PokerUtil.Card_Type_Map[i], self.isPlaneTakeSinle)
- end
- end
-
- -- 飞机带对子
- for i = PokerUtil.Less_Plane + 4, PokerUtil.Card_Max_Length do
- if i % 5 == 0 then
- table.insert(PokerUtil.Card_Type_Map[i], self.isPlanetakeDouble)
- end
- end
-
- -- 炸弹
- table.insert(PokerUtil.Card_Type_Map[4], self.isBomb)
-
- -- 王炸
- table.insert(PokerUtil.Card_Type_Map[2], self.isKingBomb)
- end
-
- -- 获得提示(cards是userdata)
- function PokerUtil:getTip(cards, lastData)
- print('jxjx 进入getTip')
- dump(cards, 'cards')
- dump(lastData, 'lastData')
- local tipResult = {}
- local lastCardInfo = self:getCardsType(lastData)
-
- if lastCardInfo.cardType < defs.CARD_TYPE.BOMB then
- local f = PokerUtil.Card_Tip_Map[lastCardInfo.cardType]
- if f then
- print(string.format('jxjx..牌型提示..%s', defs.CARD_TYPE_NAME[lastCardInfo.cardType]))
- -- tipResult = PokerUtil.Card_Tip_Map[lastCardInfo.cardType](self, cards, lastData) -- f是方法 启用initTipMap
- tipResult = self[f](self, cards, lastData) -- f是str
- end
- end
-
- -- 添加炸弹
- if lastCardInfo.cardType <= defs.CARD_TYPE.BOMB then
- print('jxjx..炸弹')
- local result = self:getBombTip(cards, lastData)
- if table.nums(result) > 0 then
- for _, bomb in ipairs(result) do
- table.insert(tipResult, bomb)
- end
- end
- end
-
- --王炸
- if lastCardInfo.cardType <= defs.CARD_TYPE.BOMB_KING then
- print('jxjx..王炸')
- local result = self:getBombKingTip(cards, lastData)
- if table.nums(result) > 0 then
- for _, bomb in ipairs(result) do -- 王炸只有1个,虽然多此一举用了循环...
- table.insert(tipResult, bomb)
- end
- end
- end
-
- dump(tipResult, 'jxjx gettip 结果')
- return tipResult
- end
-
- -- 解析牌值,将牌值分成牌值数量表和牌表
- --[[
- valueList: key具体牌值, value数量
- valueCard: key具体牌值, value标准牌值(16进制转10进制的)
- ]]
- function PokerUtil:parseCard(cards)
- local valueList = {}
- local valueCard = {}
- for k,v in ipairs(cards) do
- local value = self:getCardValue(v)
- if not valueList[value] then
- valueList[value] = 0
- end
- if not valueCard[value] then
- valueCard[value] = {}
- end
- valueList[value] = valueList[value] + 1
- table.insert(valueCard[value], v)
- end
-
- return valueList, valueCard
- end
-
- -- 解析牌值,将牌值分成牌值数量表和牌表(扩展版)
- --[[
- valueCard: key有序, value标准牌值(16进制转10进制的)
- ]]
- function PokerUtil:parseCardEx(cards)
- local temp = {}
- for k,v in ipairs(cards) do
- local value = self:getCardValue(v)
- if not temp[value] then
- temp[value] = {}
- end
- table.insert(temp[value], v)
- end
-
- local valueCard = {}
- for _,v in pairs(temp) do
- table.insert(valueCard, v)
- end
-
- return valueCard
- end
-
- -- 反解析牌值,返回key为数量,value为具体牌值的表
- --[[
- result: key数量, value具体牌值
- ]]
- function PokerUtil:reParseCard(cards)
- local valueList = self:parseCard(cards)
- local result = {{}, {}, {}, {}} -- 一副牌,最多4张
- for k,v in pairs(valueList) do
- table.insert(result[v], k)
- end
-
- return result
- end
-
- -- 通过牌的标准值,转换为具体值
- function PokerUtil:changeCardValue_Standard_To_Specific(cards)
- if type(cards) == 'number' then
- return self:getCardValue(cards)
- elseif type(cards) == 'table' then
- local result = {}
- for i, v in ipairs(cards) do
- table.insert(result, self:getCardValue(v))
- end
- return result
- end
-
- return
- end
-
- -- 判断牌组中是否包含炸弹
- function PokerUtil:getIsHaveBomb(cards)
- -- 4张
- local reValueList = self:reParseCard(cards)
- if #reValueList[4] > 0 then
- return true
- end
-
- -- 王炸
- local valueList = self:parseCard(cards)
- if (valueList[Value_Joker_Little] or 0) > 0 and (valueList[Value_Joker_Big] or 0) > 0 then
- return true
- end
-
- return false
- end
-
- -- 获得牌类型(返回类型和最小值)
- function PokerUtil:getCardsType(cards)
- local result = {min = -1, cardType = defs.CARD_TYPE.NULL}
- local maxLen = table.nums(cards)
- if maxLen == 0 then
- print('jxjx 牌长度错误,获得牌类型,牌长度是0,返回')
- return result
- end
-
- local tt = {}
- for k,v in ipairs(cards) do
- table.insert(tt, self:getCardValue(v))
- end
-
- table.sort(tt, function(a, b)
- return a < b
- end)
-
- print('jxjx 获得牌提示,长度是', maxLen)
- if PokerUtil.Card_Type_Map[maxLen] then
- print(string.format('jxjx 判断方法共有%d个', #PokerUtil.Card_Type_Map[maxLen]))
- end
-
- for i, fun in ipairs(PokerUtil.Card_Type_Map[maxLen]) do
- local isType, ct, min = fun(self, tt)
- if isType then
- result = {min = min, cardType = ct}
- print('jxjx 获得牌提示,牌的类型是', defs.CARD_TYPE_NAME[ct])
- break
- end
- end
-
- return result
- end
-
- -- 是否一手出完所有牌
- function PokerUtil:checkIsCanOneOutCard(cards, lastData)
- print('jxjx 是否一手出完所有牌')
- dump(cards, 'cards>>')
- dump(lastData, 'lastData>>')
-
- -- 压牌(如果有提示牌,并且只有1种)
- if lastData and table.nums(lastData) > 0 then
- local tips = self:getTip(cards, lastData)
- if tips and table.nums(tips) == 1 and #tips[1] == #cards then
- print('压牌,可以出完一手牌')
- return true
- end
- end
-
- -- 自己出牌(判断手中的所有牌是否可以组成某个牌型,并且没有炸弹)
- if not lastData or table.nums(lastData) <= 0 then
- local handCardType = self:getCardsType(cards)
- if handCardType.cardType > defs.CARD_TYPE.NULL and not self:getIsHaveBomb(cards) then
- print('自己出牌,可以出完一手牌')
- return true
- end
- end
-
- print('jxjx 不可一手出完所有牌')
- return false
- end
-
- -- 是否可以3带1
- function PokerUtil:can31()
- if not app.room then
- return true
- end
-
- local gameInfo = json.decode(app.room.roomInfo.strGameInfo)
- return getNumBand(0x01, (gameInfo.sanDai or 0x1)) > 0
- end
-
- -- 是否可以3带2
- function PokerUtil:can32()
- if not app.room then
- return true
- end
-
- local gameInfo = json.decode(app.room.roomInfo.strGameInfo)
- return getNumBand(0x02, (gameInfo.sanDai or 0x2)) > 0
- end
-
- -- 是否可以4带1
- function PokerUtil:can41()
- return false
- end
-
- -- 是否可以4带2(4带1对子)
- function PokerUtil:can42()
- return true
- end
-
- -- 是否可以4带单单(2个单张)
- function PokerUtil:can411()
- if not app.room then
- return true
- end
-
- local gameInfo = json.decode(app.room.roomInfo.strGameInfo)
- return getNumBand(0x02, (gameInfo.siDai or 0x02)) > 0
- end
-
- -- 是否可以4带双双(2个对子)
- function PokerUtil:can422()
- if not app.room then
- return true
- end
-
- local gameInfo = json.decode(app.room.roomInfo.strGameInfo)
- return getNumBand(0x08, (gameInfo.siDai or 0x08)) > 0
- end
-
- -----------------------------------------------------------------------------------------------------------------
- -------------------------------------- 以下是牌型提示 ------------------------------------------------------
- -----------------------------------------------------------------------------------------------------------------
-
- -- 获得单张提示
- -- tip: 先从1张按顺序获取,在从2张,最后到4张
- function PokerUtil:getSingleTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local result = {}
-
- local a = {{}, {}, {}, {}}
- for k,v in pairs(valueList) do
- table.insert(a[v], k)
- end
-
- for i = 1, 4 do
- for k2,v2 in pairs(a[i]) do
- if v2 > lastCardInfo.min then
- table.insert(result, { valueCard[v2][1] })
- end
- end
- end
-
- return result
- end
-
- -- 获得对子提示
- -- tip:直接就是从小到大,直接在2,3,4张中获取,不按是否有3张还是4张的
- function PokerUtil:getDuiZiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 2 then
- for j = 1, 2 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得三张提示
- -- tip:直接就是从小到大,直接在3,4张中获取,不按是否有3张还是4张的
- function PokerUtil:getSanZhangTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 3 then
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得顺子提示
- -- tips:先for循环最小值+1,直到13-长度(为了减少复杂度);然后在while循环中判断是否有当前出牌的长度的个数
- function PokerUtil:getShunZiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local lastCardsLen = table.nums(lastData)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 - lastCardsLen do
- local tpIdx = i
- local tpCount = 0
- local tpReplace = {}
- while tpCount < nowCardsLen and tpCount < lastCardsLen and tpIdx <= 12 do
- valueList[tpIdx] = valueList[tpIdx] or 0
- if valueList[tpIdx] <= 0 then
- break
- end
- table.insert(tpReplace, valueCard[tpIdx][1])
- tpCount = tpCount + 1
- tpIdx = tpIdx + 1
- end
- if tpCount == lastCardsLen then
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得连对提示
- -- tip:先for循环最小值+1,直到13-长度/2(为了减少复杂度,这里/2是因为连对中是一半一半相对的);然后在while循环中判断是否有当前出牌的长度的个数
- function PokerUtil:getLianDuiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local lastCardsLen = table.nums(lastData)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 - lastCardsLen / 2 do
- local tpIdx = i
- local tpCount = 0
- local tpReplace = {}
- while tpCount < nowCardsLen and tpCount < lastCardsLen and tpIdx <= 12 do
- valueList[tpIdx] = valueList[tpIdx] or 0
- if valueList[tpIdx] <= 1 then
- break
- end
- for j = 1, 2 do
- table.insert(tpReplace, valueCard[tpIdx][j])
- end
- tpCount = tpCount + 2
- tpIdx = tpIdx + 1
- end
- if tpCount == lastCardsLen then
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得三顺提示(飞机不带翅膀)
- -- tip:先for循环最小值+1,直到13-长度/3(为了减少复杂度,这里/3是因为连对中是每3分之1相对的);然后在while循环中判断是否有当前出牌的长度的个数
- function PokerUtil:getSanShunTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local lastCardsLen = table.nums(lastData)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 - lastCardsLen / 3 do
- local tpIdx = i
- local tpCount = 0
- local tpReplace = {}
- while tpCount < nowCardsLen and tpCount < lastCardsLen and tpIdx <= 12 do
- valueList[tpIdx] = valueList[tpIdx] or 0
- if valueList[tpIdx] <= 2 then
- break
- end
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[tpIdx][j])
- end
- tpCount = tpCount + 3
- tpIdx = tpIdx + 1
- end
- if tpCount == lastCardsLen then
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得3带1提示
- -- tips:直接获取判断是否有大于等于3张的牌值
- function PokerUtil:getSanDaiYiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local result = {}
-
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if ((valueList[i] or 0) == 3 and nowCardsLen > 3) or ((valueList[i] or 0) > 3 and nowCardsLen > 4) then
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得3带1对提示(3带2)
- -- tip:在for循环前,会判断是否有对子
- function PokerUtil:getSanDaiYiDuiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local reValueList = self:reParseCard(cards)
- local result = {}
-
- if table.nums(reValueList[2]) > 0 then
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 3 then
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
- end
-
- return result
- end
-
- -- 获得飞机带单提示
- -- tip:根据当前循环for的i值,往后延长最长的,如果一个111222,手中有333444555,则会提示444555
- function PokerUtil:getAirPlaneSingleTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local lastCardsLen = table.nums(lastData)
- local result = {}
-
- if table.nums(valueList) > lastCardsLen / 4 then
- for i = lastCardInfo.min + 1, 13 - lastCardsLen / 4 do
- local tpIdx = i
- local tpCount = 0
- local tpReplace = {}
- while tpCount < nowCardsLen and tpIdx <= 12 do
- valueList[tpIdx] = valueList[tpIdx] or 0
- if valueList[tpIdx] < 3 then
- break
- end
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[tpIdx][j])
- end
- tpCount = tpCount + 4
- tpIdx = tpIdx + 1
- end
- if tpCount == lastCardsLen then
- table.insert(result, tpReplace)
- end
- end
- end
-
- return result
- end
-
- -- 获得飞机带对提示
- -- tips:会先判断手牌中2张是否大于等于2个数量,jxtd 这里有bug,因为只会从对子中判断,不会冲超过2张中判断
- function PokerUtil:getAirPlaneDuiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local lastCardsLen = table.nums(lastData)
- local reValueList = self:reParseCard(cards)
- local result = {}
-
- if table.nums(reValueList[2]) >= lastCardsLen / 5 then
- for i = lastCardInfo.min + 1, 13 - lastCardsLen / 5 do
- local tpIdx = i
- local tpCount = 0
- local tpReplace = {}
- while tpCount < nowCardsLen and tpIdx <= 12 do
- valueList[tpIdx] = valueList[tpIdx] or 0
- if valueList[tpIdx] < 3 then
- break
- end
- for j = 1, 3 do
- table.insert(tpReplace, valueCard[tpIdx][j])
- end
- tpCount = tpCount + 5
- tpIdx = tpIdx + 1
- end
- if tpCount == lastCardsLen then
- table.insert(result, tpReplace)
- end
- end
- end
-
- return result
- end
-
- -- 获得4带2单提示
- -- tips:先判断手牌是否大于等于6张,然后寻找4个
- function PokerUtil:getSiDaiErSingleTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local result = {}
-
- if nowCardsLen >= 6 then
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 4 and nowCardsLen > 4 then
- for j = 1, 4 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
- end
-
- return result
- end
-
- -- 获得4带2对提示
- -- tips:会先判断手牌中2张是否大于等于2个数量,jxtd 这里有bug,因为只会从对子中判断,不会冲超过2张中判断
- function PokerUtil:getSiDaiErDuiTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local nowCardsLen = table.nums(cards)
- local reValueList = self:reParseCard(cards)
- local result = {}
-
- if table.nums(reValueList[2]) >= 2 then
- for i = lastCardInfo.min + 1, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 4 and nowCardsLen > 4 then
- for j = 1, 4 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
- end
-
- return result
- end
-
- -- 获得炸弹提示
- function PokerUtil:getBombTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local lastCardInfo = self:getCardsType(lastData)
- local result = {}
-
- local tpIndex = lastCardInfo.cardType < defs.CARD_TYPE.BOMB and 1 or lastCardInfo.min + 1
- for i = tpIndex, 13 do
- local tpReplace = {}
- if (valueList[i] or 0) >= 4 then
- for j = 1, 4 do
- table.insert(tpReplace, valueCard[i][j])
- end
- table.insert(result, tpReplace)
- end
- end
-
- return result
- end
-
- -- 获得王炸提示
- function PokerUtil:getBombKingTip(cards, lastData)
- local valueList, valueCard = self:parseCard(cards)
- local result = {}
-
- if (valueList[Value_Joker_Little] or 0) > 0 and (valueList[Value_Joker_Big] or 0) > 0 then
- local tpReplace = {}
- table.insert(tpReplace, 0x4e)
- table.insert(tpReplace, 0x4f)
- table.insert(result, tpReplace)
- end
-
- return result
- end
-
- -----------------------------------------------------------------------------------------------------------------
- -------------------------------------- 以下是检查牌型 ------------------------------------------------------
- -----------------------------------------------------------------------------------------------------------------
- --[[
- cards 是具体牌值,即1~K,从小到大排序
- ]]
-
- -- 是否是单张
- function PokerUtil:isSingle(cards)
- return true, defs.CARD_TYPE.SINGLE, cards[1]
- end
-
- -- 是否是对子
- function PokerUtil:isDouble(cards)
- if cards[1] == cards[2] then
- return true, defs.CARD_TYPE.DUIZI,cards[1]
- end
-
- return false
- end
-
- -- 是否是三张(不带)
- function PokerUtil:isThree(cards)
- if cards[1] == cards[2] and cards[2] == cards[3] then
- return true, defs.CARD_TYPE.SANZHANG, cards[1]
- end
-
- return false
- end
-
- -- 是否是顺子
- function PokerUtil:isLine(cards)
- local isHaveKindOr2 = false
- for i, val in ipairs(cards) do
- if val == Value_Joker_Little or val == Value_Joker_Big or val == Value_2 then
- isHaveKindOr2 = true
- break
- end
- end
-
- -- 顺子中不允许包括2,大王,小王
- if isHaveKindOr2 then
- return false
- end
-
- -- 检查单张总长度是否与传入相同,因为顺子是必须都是单个值
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[1]) ~= #(cards) then
- return false
- end
-
- -- 判断是否为顺子,计算最大值与最小值的差的绝对值是否与总长度-1相同
- if math.abs(cards[1] - cards[#cards]) == #cards - 1 then
- return true, defs.CARD_TYPE.SHUNZI, cards[1]
- end
-
- return false
- end
-
- -- 是否是双顺(连对)
- function PokerUtil:isDoubleLine(cards)
- local isHaveKindOr2 = false
- for i, val in ipairs(cards) do
- if val == Value_Joker_Little or val == Value_Joker_Big or val == Value_2 then
- isHaveKindOr2 = true
- break
- end
- end
-
- -- 顺子中不允许包括2,大王,小王
- if isHaveKindOr2 then
- return false
- end
-
- -- 检查2张的个数是否与总长度的一半相同,因为连对是必须都是对子值
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[2]) ~= #(cards) / 2 then
- return false
- end
-
- -- 判断是否为对子,计算最大值与最小值的差的绝对值是否与总长度/2-1相同
- if math.abs(cards[1] - cards[#cards]) == #cards/2 - 1 then
- return true, defs.CARD_TYPE.SHUANGSHUN, cards[1]
- end
-
- return false
- end
-
- -- 是否是三带一(单张)
- function PokerUtil:isThreeTakeOne(cards)
- if not self:can31() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[3]) == 1 then
- return true, defs.CARD_TYPE.SANDAIYI, reValueList[3][1]
- end
-
- return false
- end
-
- -- 是否是三带二(对子)
- function PokerUtil:isThreeTakeTwo(cards)
- if not self:can32() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[3]) == 1 and table.nums(reValueList[2]) == 1 then
- return true, defs.CARD_TYPE.SANDAIDUI, reValueList[3][1]
- end
-
- return false
- end
-
- -- 是否是四带一(单)
- function PokerUtil:isFourTakeOneSinle(cards)
- if not self:can41() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[4]) == 1 then
- return true, defs.CARD_TYPE.SIDAIYI, reValueList[4][1]
- end
-
- return false
- end
-
- -- 是否是四带一对(对子)
- function PokerUtil:isFourTakeOneDouble(cards)
- if not self:can42() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[4]) == 1 and table.nums(reValueList[2]) == 1 then
- return true, defs.CARD_TYPE.SIDAIYIDUI, reValueList[4][1]
- end
-
- return false
- end
-
- -- 是否是四带二单张
- function PokerUtil:isFourTakeTwoSinle(cards)
- if not self:can411() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[4]) == 1 then
- return true, defs.CARD_TYPE.SIDAIER, reValueList[4][1]
- end
-
- return false
- end
-
- -- 是否是四带二对子
- function PokerUtil:isFourTakeTwoDouble(cards)
- if not self:can422() then
- return false
- end
-
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[4]) == 1 and table.nums(reValueList[2]) == 2 then
- return true, defs.CARD_TYPE.SIDAIERDUI, reValueList[4][1]
- end
-
- return false
- end
-
- -- 是否是三顺(飞机不带333444)
- function PokerUtil:isPlaneNoTake(cards)
- local isHaveKindOr2 = false
- for i, val in ipairs(cards) do
- if val == Value_Joker_Little or val == Value_Joker_Big or val == Value_2 then
- isHaveKindOr2 = true
- break
- end
- end
-
- -- 三顺中不允许包括2,大王,小王
- if isHaveKindOr2 then
- return false
- end
-
- -- 检查3张的个数是否与总长度的/3相同,因为三顺是必须都是三个个值
- local reValueList = self:reParseCard(cards)
- if table.nums(reValueList[3]) ~= #(cards) / 3 then
- return false
- end
-
- -- 判断是否为对子,计算最大值与最小值的差的绝对值是否与总长度/2-1相同
- if math.abs(cards[1] - cards[#cards]) == #cards/3 - 1 then
- return true, defs.CARD_TYPE.SANSHUN, cards[1]
- end
-
- return false
- end
-
- -- 是否是飞机带单
- function PokerUtil:isPlaneTakeSinle(cards)
- -- if not self:can31() then
- -- return false
- -- end
-
- local reValueList = self:reParseCard(cards)
- local t3 = reValueList[3]
- local t4 = reValueList[4]
- for i = #t3, 1, -1 do -- 移除三张中带2的值
- if t3[i] == Value_2 then
- table.remove(t3, i)
- end
- end
-
- for i = #t4, 1, -1 do -- 移除四张中带2的值
- if t4[i] == Value_2 then
- table.remove(t4, i)
- end
- end
-
- local tpLianMin = self:tpLian(t3, t4, #cards/4)
- if tpLianMin then
- return true, defs.CARD_TYPE.AIRPLANE_SINGLE, tpLianMin.min
- end
- return false
- end
-
- -- 是否是飞机带对子
- function PokerUtil:isPlanetakeDouble(cards)
- -- if not self:can32() then
- -- return false
- -- end
-
- local reValueList = self:reParseCard(cards)
- local t2 = reValueList[2]
- local t3 = reValueList[3]
- local t4 = reValueList[4]
-
- for i = #t3, 1, -1 do -- 移除三张中带2的值
- if t3[i] == Value_2 then
- table.remove(t3, i)
- end
- end
-
- for i = #t4, 1, -1 do -- 移除四张中带2的值
- if t4[i] == Value_2 then
- table.remove(t4, i)
- end
- end
-
- local tpLianMin = self:tpLian(t3, t4, #cards/5)
-
- if tpLianMin then
- -- 判断除飞机长度外,组成对子的是否能超过飞机的个数
- local canBeDuiZiCount = #t2 + #t3 + #t4 * 2 -- 炸弹算2个对子,所以t4要*2
- print(string.format('%d可组成对子,飞机长度是%d', canBeDuiZiCount, tpLianMin.feiLen))
- local isMoreThan_2DuiZi = (canBeDuiZiCount - tpLianMin.feiLen) >= tpLianMin.feiLen
- if not isMoreThan_2DuiZi then
- return false
- end
-
- return true, defs.CARD_TYPE.AIRPLANE_DUAD, tpLianMin.min
- end
- return false
- end
-
- -- 飞机的判断
- -- tip:主要是根据3张,4张中,通过while循环获取与传入的飞机长度feiLen相同长度的值
- function PokerUtil:tpLian(la3, la4, feiLen)
- local feiLen = feiLen or 0
- local lc = {}
- for _,v in ipairs(la3) do
- table.insert(lc, v)
- end
-
- for _,v in ipairs(la4) do
- table.insert(lc, v)
- end
-
- if table.nums(lc) <= 0 then
- return nil
- end
-
- table.sort(lc, function (a, b)
- return a < b
- end)
-
- local lenEx = 1
- local feiji = {}
- local lcLen = table.nums(lc)
- for k,v in ipairs(lc) do
- lenEx = 1
- local j = k + 1
- while j <= lcLen and (feiLen == 0 or lenEx < feiLen) do
- if lc[j] ~= lc[j-1] + 1 then -- 判断是否是连续的
- break
- end
- j = j + 1
- lenEx = lenEx + 1
- end
- if lenEx == feiLen then
- table.insert(feiji, {
- feiLen = lenEx,
- min = lc[k],
- })
- end
- end
-
- if table.nums(feiji) > 0 then
- table.sort(feiji, function (a, b)
- return b.feiLen ~= a.feiLen and b.feiLen - a.feiLen or b.min - a.min
- end)
- return feiji[1]
- else
- return nil
- end
- end
-
- -- 是否是炸弹
- function PokerUtil:isBomb(cards)
- local tag = true
- local v = cards[1]
- for i, val in ipairs(cards) do
- if v ~= val then
- tag = false
- break
- end
- end
-
- if tag then
- return true, defs.CARD_TYPE.BOMB, cards[1]
- end
-
- return false
- end
-
- -- 是否是王炸
- function PokerUtil:isKingBomb(cards)
- if cards[1] == Value_Joker_Little and cards[2] == Value_Joker_Big then
- return true, defs.CARD_TYPE.BOMB_KING, cards[1]
- end
-
- return false
- end
-
- -----------------------------------------------------------------------------------------------------------------
- ---------------------------------------- 以下是配置 --------------------------------------------------------
- -----------------------------------------------------------------------------------------------------------------
-
- -- 配置
- PokerUtil.Card_Max_Length = 20 -- 手牌最多的个数
- PokerUtil.Less_Line = 5 -- 顺子最小长度
- PokerUtil.Max_Line = 12 -- 顺子最大长度(3~A)
- PokerUtil.Less_Lian_Dui = 6 -- 最小组成的连对长度
- PokerUtil.Less_Plane = 6 -- 最小组成的飞机长度
- PokerUtil.Card_Type_Map = {} -- 牌类型方法表
- PokerUtil.Card_Tip_Map = {} -- 牌提示方法表
-
- -- 牌型提示对应的方法(后面对应的是方法)
- PokerUtil.Card_Tip_Map = {
- [defs.CARD_TYPE.NULL] = nil,
- [defs.CARD_TYPE.SINGLE] = 'getSingleTip',
- [defs.CARD_TYPE.DUIZI] = 'getDuiZiTip',
- [defs.CARD_TYPE.SANZHANG] = 'getSanZhangTip',
- [defs.CARD_TYPE.SHUNZI] = 'getShunZiTip',
- [defs.CARD_TYPE.SHUANGSHUN] = 'getLianDuiTip',
- [defs.CARD_TYPE.SANSHUN] = 'getSanShunTip',
- [defs.CARD_TYPE.SANDAIYI] = 'getSanDaiYiTip',
- [defs.CARD_TYPE.SANDAIDUI] = 'getSanDaiYiDuiTip',
- [defs.CARD_TYPE.SIDAIYI] = nil,
- [defs.CARD_TYPE.SIDAIYIDUI] = nil,
- [defs.CARD_TYPE.SIDAIER] = 'getSiDaiErSingleTip',
- [defs.CARD_TYPE.SIDAIERDUI] = 'getSiDaiErDuiTip',
- [defs.CARD_TYPE.AIRPLANE_SINGLE] = 'getAirPlaneSingleTip',
- [defs.CARD_TYPE.AIRPLANE_DUAD] = 'getAirPlaneDuiTip',
- [defs.CARD_TYPE.BOMB] = 'getBombTip',
- [defs.CARD_TYPE.BOMB_KING] = 'getBombKingTip',
- }
-
- -- 初始化牌提示方法,不能用表驱动,因为子类重写时,调用的话,还是用的父类方法
- -- function PokerUtil:initTipMap()
- -- PokerUtil.Card_Tip_Map = {
- -- [defs.CARD_TYPE.NULL] = nil,
- -- [defs.CARD_TYPE.SINGLE] = self.getSingleTip,
- -- [defs.CARD_TYPE.DUIZI] = self.getDuiZiTip,
- -- [defs.CARD_TYPE.SANZHANG] = self.getSanZhangTip,
- -- [defs.CARD_TYPE.SHUNZI] = self.getShunZiTip,
- -- [defs.CARD_TYPE.SHUANGSHUN] = self.getLianDuiTip,
- -- [defs.CARD_TYPE.SANSHUN] = self.getSanShunTip,
- -- [defs.CARD_TYPE.SANDAIYI] = self.getSanDaiYiTip,
- -- [defs.CARD_TYPE.SANDAIDUI] = self.getSanDaiYiDuiTip,
- -- [defs.CARD_TYPE.SIDAIYI] = nil,
- -- [defs.CARD_TYPE.SIDAIYIDUI] = nil,
- -- [defs.CARD_TYPE.SIDAIER] = self.getSiDaiErSingleTip,
- -- [defs.CARD_TYPE.SIDAIERDUI] = self.getSiDaiErDuiTip,
- -- [defs.CARD_TYPE.AIRPLANE_SINGLE] = self.getAirPlaneSingleTip,
- -- [defs.CARD_TYPE.AIRPLANE_DUAD] = self.getAirPlaneDuiTip,
- -- [defs.CARD_TYPE.BOMB] = self.getBombTip,
- -- [defs.CARD_TYPE.BOMB_KING] = self.getBombKingTip,
- -- }
- -- end
-
- return PokerUtil
|