斗地主牌型算法一

panger0条评论 1,842 次浏览

首先先弄清楚有那些牌型:

火箭or王炸:即双王(大王和小王),最大的牌。

炸弹:四张同数值牌(如四个 7 )。

单牌:单个牌(如红桃 5 )。

对牌:数值相同的两张牌(如梅花 4+ 方块 4 )。

三张牌:数值相同的三张牌(如三个 J )。

三带一:数值相同的三张牌 + 一张单牌或一对牌。例如: 333+6 或 444+99

单顺:五张或更多的连续单牌(如: 45678 或 78910JQK )。不包括 2 点和双王。

双顺:三对或更多的连续对牌(如: 334455 、 7788991010JJ )。不包括 2 点和双王。

三顺:二个或更多的连续三张牌(如: 333444 、 555666777888 )。不包括 2 点和双王。

飞机带翅膀:三顺+同数量的单牌(或同数量的对牌)。

如: 444555+79 或 333444555+7799JJ

四带二:四张牌+两手牌。(注意:四带二不是炸弹)。

如: 5555 + 3 + 8 或 4444 + 55 + 77 。

这里我按照牌型的大小定义了一些变量方便在以后代码中使用

—-各种牌型的对应数字

ERROR_CARDS = 0 --错误牌型
SINGLE_CARD = 1 --单牌
DOUBLE_CARD = 2 --对子
THREE_CARD = 3 --3不带
THREE_ONE_CARD = 4 --3带1
THREE_TWO_CARD = 5 --3带2
BOMB_TWO_CARD = 6 --四个带2张单牌
BOMB_FOUR_CARD = 7 --四个带2对
CONNECT_CARD = 8 --连牌
COMPANY_CARD = 9 --连队
AIRCRAFT_CARD = 10 --飞机不带
AIRCRAFT_WING = 11 --飞机带单牌或对子
BOMB_CARD = 12 --炸弹
KINGBOMB_CARD = 13 --王炸

先来定义数字代表扑克中的牌的规则

我用3到13代表扑克中的3到K,再用14代表A,15 代表 2 (这样在以后的牌型判断和比较的时候方便)。花色用百位来表示(如方块3就是103,黑桃2就是415),大小王是116,117。

先写两个方法得到数字代表的牌值和花色

  • 获得扑克牌的牌值
function getValue(card)
    return card % 100
end
  • 获得扑克牌的花色
function getSuit(card)
    return card / 100
end

在写一个方法判断数字是否是牌(有时候传进来的数字可能去掉了花色)

–测试所有的牌是否都是扑克牌
function isCards(cards)
for k,c in pairs(cards) do
if c < 100 then
if 3 > c or 17 < c then
return false
end
else
if getValue(c) > 17 or getValue(c) < 3 then
return false
end
end
end
return true
end

接下来就是牌型判断了先判断几个容易的牌型(牌数小于5的)

把所有的代表牌的数字放在一个table中传进去得到一个牌值的table

function getCardsTabValue(cards)
    local tmp = {}
    for k, v in pairs(cards or {}) do
        if type(v) ~= "table" then
            tmp[k] = v % 100
        else
            tmp[k] = CardUtils.getCardsTabValue(v)
        end
    end
    return tmp
end

注意下面所有的判断都是先将数字去掉花色之后的判断

// 单牌
function isSingle(cards)
    if not CardUtils.isCards(cards)then
        return false
    end
    if 1 == #cards then
        return true
    end
    return false
end

// 对子
function isDouble(cards)
    if not CardUtils.isCards(cards) then
        return false
    end
    if 2 == #cards then
        if cards[1] == cards[2] then
            return true
        end
    end
    return false
end

// 王炸
function isKingBomb(cards)
    if not CardUtils.isCards(cards) or 2 ~= #cards then
        return false
    end
    table.sort(cards)
    if cards[1] == 16 and cards[2] == 17 then
        return true
    end
    return false
end

// 3不带 只要判断三个牌值相等
function isThree(cards)
    if not CardUtils.isCards(cards) or 3 ~= #cards then
        return false
    end
    if cards[1] == cards[2] and cards[1] == cards[3] then
        return true
    end
    return false
end

// 3带1 先对数字排序 再判断带的牌是在那个位置 (4446,3444)再将带的牌移除判断剩下的三个牌是不是 3不带
function isThreeOne(cards)
    if not CardUtils.isCards(cards) or 4 ~= #cards then
        return false
    end
    table.sort(cards)
    if cards[1] ~=cards[2] then
        table.remove(cards, 1)
    else
        table.remove(cards, 4)
    end
    if isThree(cards) then
        return true
    end
    return false
end

// 3带对子 先排序 头尾都是对子而且中间的牌等于头或者尾的值(55577,44555)
function isThreeTwo( cards )
    if not CardUtils.isCards(cards) or 5 ~= #cards then
        return false
    end
    table.sort(cards)
    if cards[1] == cards[2] and cards[4] == cards[5] then
        if cards[3] == cards[2] or cards[3] == cards[4] then
            return true
        end
    end
    return false
end

// 炸弹
function isBomb( cards )
    if not CardUtils.isCards(cards) or 4 ~= #cards then
        return false
    end
    if cards[1] == cards[2] and cards[2] == cards[3] and cards[3] == cards[4] then
        return true
    end
    return
end


发表评论

? razz sad evil ! smile oops grin eek shock ??? cool lol mad twisted roll wink idea arrow neutral cry mrgreen