斗地主牌型算法一
首先先弄清楚有那些牌型:
火箭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