原文地址:https://www.namidame.tech/Lua-Texas.html
本文提供了一种用Lua实现的德州扑克牌型、得分及成牌选择算法,是在公司空余时间老板要求练手写的算法。。。包括了代码和测试用例,代码可以应用在德州扑克手游的牌型计算模块中。
这里有几个文件,直接上代码
安装Lua运行环境后命令行运行main.lua文件即可
其中CardDealer文件是自动发牌的,由于测试用例需要自己编写,这个类也没什么用了
main.lua
-- Author: luyuejun
-- Date: 2017/6/15
require("CardUtil")
require("TableUtil")
require("CardDealer")
-- "高牌" 1
-- "一对" 2
-- "两对" 3
-- "三条" 4
-- "顺子" 5
-- "同花" 6
-- "葫芦" 7
-- "四条" 8
-- "同花顺" 9
-- 以下为测试用例
local datas = {}
table.insert(datas, {input={H={{1,1},{1,2}},P={{1,3},{1,4},{1,5}}},expectOutput={T=9,S=90504030201,C={{1,1},{1,2},{1,3},{1,4},{1,5}}}})
table.insert(datas, {input={H={{4,10},{4,12}},P={{4,11},{4,13},{4,1}}},expectOutput={T=9,S=91413121110,C={{4,10},{4,11},{4,12},{4,13},{4,1}}}})
table.insert(datas, {input={H={{4,10},{4,12}},P={{4,11},{4,8},{4,1}}},expectOutput={T=6,S=61412111008,C={{4,8},{4,10},{4,11},{4,12},{4,1}}}})
table.insert(datas, {input={H={{4,10},{4,12}},P={}},expectOutput={T=1,S=11210,C={{4,10},{4,12}}}})
table.insert(datas, {input={H={{4,10},{4,12},{3,12}},P={}},expectOutput={T=2,S=2121210,C={{4,10},{4,12},{3,12}}}})
table.insert(datas, {input={H={{1,12},{4,12}},P={{3,12}}},expectOutput={T=4,S=4121212,C={{1,12},{4,12},{3,12}}}})
table.insert(datas, {input={H={{1,1},{1,13}},P={{1,12}}},expectOutput={T=1,S=1141312,C={{1,12},{1,13},{1,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{1,12}}},expectOutput={T=2,S=2141412,C={{1,12},{2,1},{1,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,1}}},expectOutput={T=4,S=4141414,C={{1,1},{2,1},{3,1}}}})
table.insert(datas, {input={H={{1,1},{2,13}},P={{3,2},{3,3}}},expectOutput={T=1,S=114130302,C={{3,2},{3,3},{2,13},{1,1}}}})
table.insert(datas, {input={H={{1,1},{2,11}},P={{3,1},{3,3}}},expectOutput={T=2,S=214141103,C={{3,3},{2,11},{1,1},{3,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{4,2},{3,2}}},expectOutput={T=3,S=314140202,C={{4,2},{3,2},{1,1},{2,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,1},{3,2}}},expectOutput={T=4,S=414141402,C={{3,2},{3,1},{1,1},{2,1}}}})
table.insert(datas, {input={H={{4,4},{3,4}},P={{4,2},{3,2}}},expectOutput={T=3,S=304040202,C={{3,2},{4,2},{4,4},{3,4}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,1},{4,1}}},expectOutput={T=8,S=814141414,C={{1,1},{2,1},{3,1},{4,1}}}})
table.insert(datas, {input={H={{1,1},{2,2}},P={{3,2},{4,2},{1,2}}},expectOutput={T=8,S=80202020214,C={{1,1},{1,2},{2,2},{3,2},{4,2}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,1},{4,1},{1,2}}},expectOutput={T=8,S=81414141402,C={{1,2},{1,1},{2,1},{3,1},{4,1}}}})
table.insert(datas, {input={H={{1,1},{2,2}},P={{3,4},{4,7},{1,6}}},expectOutput={T=1,S=11407060402,C={{2,2},{3,4},{1,6},{4,7},{1,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,4},{4,7},{1,6}}},expectOutput={T=2,S=21414070604,C={{3,4},{1,6},{4,7},{1,1},{2,1}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,4},{4,1},{1,6}}},expectOutput={T=2,S=20202140604,C={{3,4},{1,6},{4,1},{1,2},{2,2}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,1},{4,1},{1,6}}},expectOutput={T=3,S=31414020206,C={{1,6},{1,2},{2,2},{3,1},{4,1}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,3},{4,3},{1,1}}},expectOutput={T=3,S=30303020214,C={{1,1},{1,2},{2,2},{3,3},{4,3}}}})
table.insert(datas, {input={H={{1,2},{2,1}},P={{3,1},{4,1},{1,6}}},expectOutput={T=4,S=41414140602,C={{1,2},{1,6},{2,1},{3,1},{4,1}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,2},{4,1},{1,6}}},expectOutput={T=4,S=40202021406,C={{1,6},{4,1},{2,2},{1,2},{3,2}}}})
table.insert(datas, {input={H={{1,2},{2,1}},P={{3,3},{4,4},{1,5}}},expectOutput={T=5,S=50504030201,C={{2,1},{1,2},{3,3},{4,4},{1,5}}}})
table.insert(datas, {input={H={{1,13},{2,1}},P={{3,12},{4,11},{1,10}}},expectOutput={T=5,S=51413121110,C={{1,10},{4,11},{3,12},{1,13},{2,1}}}})
table.insert(datas, {input={H={{1,13},{2,9}},P={{3,12},{4,11},{1,10}}},expectOutput={T=5,S=51312111009,C={{2,9},{1,10},{4,11},{3,12},{1,13}}}})
table.insert(datas, {input={H={{1,1},{1,2}},P={{1,4},{1,3},{1,8}}},expectOutput={T=6,S=61408040302,C={{1,2},{1,3},{1,4},{1,8},{1,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{1,12},{1,11},{1,10},{1,4}}},expectOutput={T=6,S=61412111004,C={{1,4},{1,10},{1,11},{1,12},{1,1}}}})
table.insert(datas, {input={H={{1,3},{2,3}},P={{3,3},{4,1},{4,3},{1,4}}},expectOutput={T=8,S=80303030314,C={{4,1},{1,3},{2,3},{3,3},{4,3}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,1},{4,4},{4,3},{1,4}}},expectOutput={T=7,S=71414140404,C={{1,4},{4,4},{1,1},{2,1},{3,1}}}})
table.insert(datas, {input={H={{1,1},{2,1}},P={{3,3},{4,3},{1,3},{1,4}}},expectOutput={T=7,S=70303031414,C={{1,1},{2,1},{3,3},{4,3},{1,3}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,3},{4,3},{1,1},{3,10}}},expectOutput={T=3,S=30303020214,C={{1,1},{1,2},{2,2},{3,3},{4,3}}}})
table.insert(datas, {input={H={{1,2},{2,2}},P={{3,3},{4,3},{1,1},{3,10},{4,10}}},expectOutput={T=3,S=31010030314,C={{1,1},{3,3},{4,3},{3,10},{4,10}}}})
table.insert(datas, {input={H={{1,1},{1,2}},P={{1,3},{1,4},{1,5},{4,12},{4,13}}},expectOutput={T=9,S=90504030201,C={{1,1},{1,2},{1,3},{1,4},{1,5}}}})
table.insert(datas, {input={H={{4,10},{4,12}},P={{4,11},{4,13},{4,1},{2,1}}},expectOutput={T=9,S=91413121110,C={{4,10},{4,11},{4,12},{4,13},{4,1}}}})
require("CardTest")
CardTest.test(datas)
CardUtil.lua
-- Author: luyuejun
-- Date: 2017/6/15
require("TableUtil")
DEBUG_LOG = false
CARD_POINTS = {
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E
}
TYPE_POINTS = {
"01","02","03","04",
"05","06","07","08",
"09","10","11","12",
"13","14"
}
PAI_XING_STRING = {
"高牌",
"一对",
"两对",
"三条",
"顺子",
"同花",
"葫芦",
"四条",
"同花顺",
}
Card = {
hua = 1,
dian = 1,
isHand = false,
}
Card.__index = Card
function printC(card)
print("card===")
print("hua=",card.hua,"dian=",card.dian)
print("card===")
end
function printHD(tb)
CardUtil.printHuaDic(tb)
end
function printDD(tb)
CardUtil.printDianDic(tb)
end
function Card:new(hua, dian, isHand)
local o = {}
setmetatable(o, self)
o.hua = hua
o.dian = dian
o.isHand = isHand or false
return o
end
function Card:getHua()
return self.hua
end
function Card:getDian()
return self.dian
end
function Card:IsHand()
return self.isHand
end
CardUtil = {}
function CardUtil.getCardInfo(hands, publics)
local tb = hands
TableUtil.concat(tb, publics)
TableUtil.print(tb)
end
function CardUtil.isTongHua(tb)
local flag = false
local huas = {0,0,0,0}
for i,v in ipairs(tb) do
huas[v.hua] = huas[v.hua] + 1
end
for i,v in ipairs(huas) do
if v >= 5 then
return true, i
end
end
return false
end
function CardUtil.isTongHuaVecShunZi(tb)
local flag = false
local curIndex = #tb
local preIndex = #tb-1
for i = #tb, 2, -1 do
for j = i, i-3, -1 do
curIndex = j
preIndex = j - 1
-- print("i = ",i,"j = ",j)
-- print("compare ",curIndex," ",preIndex)
if tb[preIndex] == nil then
return false
elseif curIndex == #tb then
if tb[curIndex].dian == 1 then
if tb[preIndex].dian ~= 13 then -- TJQKA的处理
break
end
elseif tb[curIndex].dian ~= tb[preIndex].dian + 1 then
break
end
elseif tb[curIndex].dian ~= tb[preIndex].dian + 1 then
break
elseif curIndex == i - 3 then --比完一轮5张都没断,即是顺子
local isASpecial = false
if tb[preIndex].dian == 1 then isASpecial = true end
local cards = {}
for k=i-4,i do
-- print("insert ",k)
table.insert(cards, tb[k])
end
return true, cards, isASpecial
end
end
end
return false
end
-- A有两个位置,权值1和14
function CardUtil.getDianDicSpec(tb)
local dians = {
{},{},{},{},
{},{},{},{},
{},{},{},{},
{},{}
}
for i,v in ipairs(tb) do
-- print("insert into dian=", v.dian)
table.insert(dians[v.dian], v)
if v.dian == 1 then
table.insert(dians[14], v)
end
end
return dians
end
-- A只有权值14
function CardUtil.getDianDic14(tb)
local dians = {
{},{},{},{},
{},{},{},{},
{},{},{},{},
{},{}
}
for i,v in ipairs(tb) do
if v.dian == 1 then
table.insert(dians[14], v)
else
table.insert(dians[v.dian], v)
end
end
return dians
end
function CardUtil.printDianDic(dictionary)
print("dianDic=")
CardUtil.printDic(dictionary)
print("")
end
function CardUtil.getHuaDic(tb)
local huas = {
{},{},{},{},
}
local As = { -- 先将A存起来,最后再放进每一种花色里,与默认A权值为14类似
{},{},{},{},
}
for i,v in ipairs(tb) do
-- print("insert into dian=", v.dian)
if v.dian == 1 then
table.insert(As[v.hua], v)
else
table.insert(huas[v.hua], v)
end
end
for i,hua in ipairs(As) do
for _,v in pairs(hua) do
table.insert(huas[i], v)
end
end
return huas
end
function CardUtil.printHuaDic(dictionary)
print("huaDic=")
CardUtil.printDic(dictionary)
print("")
end
function CardUtil.printDic(dictionary)
for i, v in ipairs(dictionary) do
TableUtil.print(v)
end
end
function CardUtil.isSiTiao(dictionary)
for i,v in ipairs(dictionary) do
if #v >= 4 then
-- 拿出这四张牌
local cards = {}
for _, v1 in pairs(v) do
table.insert(cards, v1)
end
-- 找出除四条外最大一张牌
for j = #dictionary, 1, -1 do
if i ~= j and #dictionary[j] > 0 then
table.insert(cards, 1, dictionary[j][1])
return true, cards
end
end
return true, cards -- 四张卡时在这里返回
end
end
return false
end
function CardUtil.isHuLu( dictionary )
-- body
local dian3 = 0 -- 最大三条所在点数
local dian2 = 0 -- 最大一对所在点数
for i = #dictionary, 1, -1 do -- 倒序查找,从最大的找起
if #dictionary[i] == 3 then
if dian3 == 0 then
dian3 = i
elseif dian2 == 0 then -- 如果已经取出最大的三条,应从第二大的三条里取两张作为一对
dian2 = i
end
elseif #dictionary[i] == 2 then -- 这里有可能从三条里面拿,例如AAAKKK8
if dian2 == 0 then
dian2 = i
end
end
if dian3 > 0 and dian2 > 0 then
break
end
end
if dian3 > 0 and dian2 > 0 then
-- 先插入权值小的一对,再插入权值大的三条
local cards = {}
table.insert(cards, dictionary[dian2][1])
table.insert(cards, dictionary[dian2][2])
for _,v in pairs(dictionary[dian3]) do
table.insert(cards, v)
end
return true, cards
else
return false
end
end
function CardUtil.isSanTiao( dictionary )
-- body
local maxSame = 0
local dian = 0
local hasPair = false
for i,v in ipairs(dictionary) do
if #v >= maxSame then
maxSame = #v
dian = i
end
if #v == 2 then
hasPair = true
end
end
if maxSame == 3 and not hasPair then
local cards = {}
-- 拿出最大的两张牌,不能是一对
for i = #dictionary, 1, -1 do
if #dictionary[i] == 1 then
if #cards == 0 then
table.insert(cards, dictionary[i][1])
elseif #cards == 1 then
table.insert(cards, 1, dictionary[i][1]) -- 为了按牌型升序排列,例如A8333
end
end
end
-- 拿出最大的三条
for i = 1, 3 do
table.insert(cards, dictionary[dian][i])
end
return true, cards
else
return false
end
end
function CardUtil.isTwoPairs(dictionary)
if #dictionary[1] > 0 and dictionary[1][1].dian == 1 then
dictionary[1] = {}
end
local pairCount = 0
local maxSame = 0
local maxPairIndex = 0
local secMaxPairIndex = 0
for i = #dictionary, 1, -1 do
if #dictionary[i] == 2 then
pairCount = pairCount + 1
if maxPairIndex == 0 then
maxPairIndex = i
elseif secMaxPairIndex == 0 then
secMaxPairIndex = i
end
end
if #dictionary[i] >= maxSame then
maxSame = #dictionary[i]
end
end
if pairCount >= 2 and maxSame == 2 then
local cards = {}
-- 取出最大的一张
for i = #dictionary, 1, -1 do
if #dictionary[i] >= 1 and i ~= maxPairIndex and i ~= secMaxPairIndex then -- 剩下的一张可能从第三对两对里取,比如AAKKJJ
table.insert(cards, dictionary[i][1])
break
end
end
-- 取出最大的两对
for i = 1, 2 do table.insert(cards, dictionary[secMaxPairIndex][i]) end -- 倒序
for i = 1, 2 do table.insert(cards, dictionary[maxPairIndex][i]) end
return true, cards
else
return false
end
end
function CardUtil.isOnePair(dictionary)
local pairCount = 0
local maxSame = 0
local pairIndex = 0
for i,v in ipairs(dictionary) do
if #v == 2 then
pairCount = pairCount + 1
if pairIndex == 0 then
pairIndex = i
end
end
if #v >= maxSame then
maxSame = #v
end
end
if pairCount == 1 then
local cards = {}
-- 取最大的三张单牌
for i = #dictionary, 1, -1 do
if #dictionary[i] == 1 then
if #cards < 3 then
table.insert(cards, 1, dictionary[i][1])
else
break
end
end
end
-- 取出对子
for i = 1,2 do table.insert(cards, dictionary[pairIndex][i]) end
return true, cards
else
return false
end
end
function CardUtil.getHighCard(dictionary)
local cards = {}
for i = #dictionary, 1, -1 do
if #cards < 5 then
if #dictionary[i] == 1 then
local hasElement = false
for _,v in pairs(cards) do
if dictionary[i][1].dian == v.dian then
hasElement = true
end
end
if not hasElement then
table.insert(cards, 1, dictionary[i][1])
end
end
else
break
end
end
return cards
end
function CardUtil.isShunZiByDic(dictionary)
for i = 14, 5, -1 do
if #dictionary[i] > 0 then
for j = i, i-4, -1 do
-- print("i = ",i,"j = ",j)
-- print("compare ",curIndex," ",nextIndex)
if #dictionary[j] == 0 then
break
elseif j == i - 4 then --比完一轮都没断,即是顺子
local cards = {}
local isASpecial = false
for k = j,i do
if k == j and dictionary[k][1].dian == 1 then isASpecial = true end --A2345的情况
table.insert(cards, dictionary[k][1])
end
return true, cards, isASpecial
end
end
end
end
return false
end
function CardUtil.isTongHuaByDic(dictionary)
for i,v in ipairs(dictionary) do
if #v >= 5 then
return true, v
end
end
return false
end
-- tb 从点数小到大排列
-- 当isASpecial为true时,A的权值由正常的14变为1,例如A2345
function CardUtil.getCardPoint(tb, paiXing, isASpecial)
local paiXingPoint = TYPE_POINTS[paiXing]
local strPoint = ""
isASpecial = isASpecial or false -- 正常情况A权值为14
for i,v in ipairs(tb) do
if v.dian < 10 then
if v.dian == 1 then
if isASpecial then
strPoint = strPoint.."01"
else
strPoint = "14"..strPoint
end
else
strPoint = "0"..tostring(v.dian)..strPoint
end
else
strPoint = tostring(v.dian)..strPoint
end
end
strPoint = paiXingPoint..strPoint
local point = tonumber(strPoint)
return point
end
-- 确定牌型
-- 按牌型不同算分
--[[
主要思路:
将手牌与公共牌合并,并按点数升序排序
A一般权值为14,只有在顺子/同花顺中的A2345中才有可能权值为1
将牌按点数分别装入索引1到14数组中,getDianDicSpec中A会放入1和14两个数组中,即有两个权值;
getDianDic14中A只会放入14数组中,即只有一个权值
getHuaDic按花色放入四个数组
1.先判断是否同花顺:判断是否同花,若是,则判断“同花的数组”是否同时为顺子
2.判断是否四条,注意第5张牌有可能从对子或三条里面拿
3.判断是否葫芦,注意第4,5张牌可能从另外的三条里面拿,如3334447
4.判断是否同花,这在同花顺时已经判断过
5.判断是否顺子,这里不可以用判断同花顺时的结果,因为那只是判断同花的几张牌是否顺子,
并未包含其他花色的牌,比如红桃45679+黑桃8,红桃的数组不是顺子,但56789是顺子
为此写了两个判断顺子的函数isTongHuaVecShunZi/isShunzi
6.判断是否三条,这时不会有另外的对子或三条,否则早就判断为葫芦
7.判断是否两对,注意可能有三对的情况
8.判断是否一对
9.若以上都不是,直接判断为高牌
--]]
-- 牌型得分
-- "高牌" 1
-- "一对" 2
-- "两对" 3
-- "三条" 4
-- "顺子" 5
-- "同花" 6
-- "葫芦" 7
-- "四条" 8
-- "同花顺" 9
-- 输入
-- hands: 手牌table,例如{{1,2},{3,4}}
-- publics: 公共牌table,可有0/3/4/5张公共牌,例如{{3,3},{4,1},{4,3},{1,4}}
-- 输出
-- paiXing:成牌牌型,例如9,为同花顺
-- cardPoint:牌型得分,例如91413121110,前1或2位为牌型分值,和成牌牌型相对应,后面为每张牌的得分,直接比较得分可知牌型间大小
-- returnVec:最大成牌,返回最大牌型的几张牌,例如{{4,10},{4,11},{4,12},{4,13},{4,1}}
function CardUtil.calculatePoint(hands, publics)
local tb = TableUtil.concat(hands, publics)
TableUtil.sort(tb)
local dianDicSp = CardUtil.getDianDicSpec(tb)
if DEBUG_LOG then CardUtil.printDianDic(dianDicSp) end
local dianDic14 = CardUtil.getDianDic14(tb)
if DEBUG_LOG then CardUtil.printDianDic(dianDic14) end
local huaDic = CardUtil.getHuaDic(tb)
if DEBUG_LOG then CardUtil.printHuaDic(huaDic) end
local isTongHua, tongHuaVec = CardUtil.isTongHuaByDic(huaDic)
if DEBUG_LOG then print("isTongHua=", isTongHua) end
if DEBUG_LOG then if tongHuaVec then printT(tongHuaVec) end end
local isTongHuaShun = false
local isASpecial = false
local isTongHuaVecShunZi = false
local tongHuaShunVec = {}
if isTongHua then
if tongHuaVec[#tongHuaVec].dian == 1 then -- 需要处理一下vec
if DEBUG_LOG then print("special") end
local tmpVec = {}
for _,v in pairs(tongHuaVec) do
table.insert(tmpVec, v)
end
table.insert(tmpVec, 1, tongHuaVec[#tongHuaVec]) -- 如果有后面A,将A也加入最前面,类似生成dianDicSp
if DEBUG_LOG then printT(tmpVec) end
isTongHuaVecShunZi, tongHuaShunVec, isASpecial = CardUtil.isTongHuaVecShunZi(tmpVec)
else
isTongHuaVecShunZi, tongHuaShunVec, isASpecial = CardUtil.isTongHuaVecShunZi(tongHuaVec)
end
isTongHuaShun = isTongHua and isTongHuaVecShunZi
end
if DEBUG_LOG then print("isTongHuaShun=",isTongHuaShun) end
local typePoint = 0
local cardPoint = 0
local totalPoint = 0 -- 返回的牌型得分
local paiXing = 0 -- 返回的牌型
local returnVec = {} -- 返回选择哪几张牌
if isTongHuaShun then -- 同花顺
if DEBUG_LOG then print("tonghuashun") end
if DEBUG_LOG then printT(tongHuaShunVec) end
paiXing = 9
cardPoint = CardUtil.getCardPoint(tongHuaShunVec, paiXing, isASpecial)
returnVec = tongHuaShunVec -- 拿出同花的数组判断,如果也是顺子,则是同花顺,见上
else
local isSiTiao, siTiaoVec = CardUtil.isSiTiao(dianDic14)
if DEBUG_LOG then print("isSiTiao=",isSiTiao) end
if DEBUG_LOG then if siTiaoVec then TableUtil.print(siTiaoVec) end end
if isSiTiao then -- 四条
if DEBUG_LOG then print("siTiao") end
paiXing = 8
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(siTiaoVec, paiXing)
returnVec = siTiaoVec
else
local isHuLu, huLuVec = CardUtil.isHuLu(dianDic14)
if DEBUG_LOG then print("isHuLu= ",isHuLu) end
if DEBUG_LOG then if isHuLu then TableUtil.print(huLuVec) end end
if isHuLu then -- 葫芦
if DEBUG_LOG then print("huLu") end
paiXing = 7
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(huLuVec, paiXing)
returnVec = huLuVec
elseif isTongHua then --同花
if DEBUG_LOG then
print("tonghua")
if tongHuaVec then printT(tongHuaVec) end
end
paiXing = 6
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(tongHuaVec, paiXing)
returnVec = tongHuaVec
else
local isShunZi, shunZiVec, isASpecial = CardUtil.isShunZiByDic(dianDicSp) -- 只有顺子特殊处理,当A2345时权值为1
if DEBUG_LOG then
print("isShunzi=",isShunZi)
if shunZiVec then printT(shunZiVec) end
end
if isShunZi then--顺子
if DEBUG_LOG then print("shunzi") end
paiXing = 5
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(shunZiVec, paiXing, isASpecial)
returnVec = shunZiVec
else
local isSanTiao, sanTiaoVec = CardUtil.isSanTiao(dianDic14)
if DEBUG_LOG then print("isSanTiao=",isSanTiao) end
if DEBUG_LOG then if isSanTiao then TableUtil.print(sanTiaoVec) end end
if isSanTiao then -- 三条
if DEBUG_LOG then print("santiao") end
paiXing = 4
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(sanTiaoVec, paiXing)
returnVec = sanTiaoVec
else
local isTwoPairs, twoPairsVec = CardUtil.isTwoPairs(dianDic14)
if DEBUG_LOG then print("isTwoPairs=",isTwoPairs) end
if DEBUG_LOG then if isTwoPairs then TableUtil.print(twoPairsVec) end end
if isTwoPairs then -- 两对
if DEBUG_LOG then print("two pairs") end
paiXing = 3
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(twoPairsVec, paiXing)
returnVec = twoPairsVec
else
local isOnePair, onePairVec = CardUtil.isOnePair(dianDic14)
if DEBUG_LOG then print("isOnePair=",isOnePair) end
if DEBUG_LOG then if isOnePair then TableUtil.print(onePairVec) end end
if isOnePair then -- 一对
if DEBUG_LOG then print("one pair") end
paiXing = 2
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(onePairVec, paiXing)
returnVec = onePairVec
else -- 高牌
if DEBUG_LOG then print("isHighCard= ", true) end
local cards = CardUtil.getHighCard(dianDic14)
if DEBUG_LOG then
printT(cards)
print("high cards")
end
paiXing = 1
typePoint = TYPE_POINTS[paiXing]
cardPoint = CardUtil.getCardPoint(cards, paiXing)
returnVec = cards
end
end
end
end
end
end
end
totalPoint = typePoint + cardPoint
if DEBUG_LOG then print("totalPoint=",totalPoint) end
return paiXing, cardPoint, returnVec
end
CardTest.lua
-- Author: luyuejun
-- Date: 2017/6/15
require("CardUtil")
CardTest = {}
CardTest.__index = CardTest
function CardTest:new()
local o = {}
setmetatable(o, self)
return o
end
function CardTest.test(datas)
local correct = 0
local incorrect = 0
for i,v in ipairs(datas) do
local inputData = v.input
local expectOutPutData = v.expectOutput
local flag = CardTest.testOne(inputData, expectOutPutData)
if flag then correct = correct + 1
else incorrect = incorrect + 1 end
end
print("")
print("correct=",correct)
print("error= ",incorrect)
end
function CardTest.testOne(inputData, expectOutPutData)
local inputHands = inputData["H"]
local inputPublics = inputData.P
local hands = {}
local publics = {}
for _,v in pairs(inputHands) do
local card = Card:new(v[1], v[2], true)
table.insert(hands, card)
end
for _,v in pairs(inputPublics) do
local card = Card:new(v[1], v[2], false)
table.insert(publics, card)
end
expectOutPutCardType = expectOutPutData.T
expectOutPutScore = expectOutPutData.S
expectOutPutCards = expectOutPutData.C
--printT(expectOutPutCards)
local outPutCardType, outPutScore, outPutCards = CardUtil.calculatePoint(hands, publics)
print("牌型 = "..PAI_XING_STRING[outPutCardType])
print("得分 = "..outPutScore)
print("牌组 = ")
printT(outPutCards)
local isCardType = CardTest.verifyCardType(expectOutPutCardType, outPutCardType)
local isScore = CardTest.verifyScore(expectOutPutScore, outPutScore)
local isCards = CardTest.verifyCards(expectOutPutCards, outPutCards)
if isCardType and isScore and isCards then
return true
else
return false
end
end
function CardTest.verifyCardType(expectOutPutCardType, outPutCardType)
if expectOutPutCardType == outPutCardType then
return true
else
print("out put card type expected:"..expectOutPutCardType)
print("output: "..outPutCardType)
return false
end
end
function CardTest.verifyScore(expectOutPutScore, outPutScore)
if expectOutPutScore == outPutScore then
return true
else
print("out put score expected:"..expectOutPutScore)
print("output: "..outPutScore)
return false
end
end
function CardTest.verifyCards(expectOutPutCards, outPutCards)
local flag = true
for i,v in ipairs(expectOutPutCards) do
-- print("compare-----")
-- printC(outPutCards[i])
if not CardTest.sameCard(v, outPutCards[i]) then
print("out put cards "..tostring(i).." expected:")
print("hua=",v[1],"dian=",v[2])
print("output:")
printC(outPutCards[i])
flag = false
end
end
return flag
end
function CardTest.sameCard(inputCard, outPutCard)
if inputCard[2] == outPutCard.dian then
return true
else
return false
end
end
TableUtil.lua
-- Author: luyuejun
-- Date: 2017/6/15
TableUtil = {}
function printT(tb)
TableUtil.print(tb)
end
function TableUtil.concat(tb1, tb2)
local newTb = {}
for i,v in pairs(tb1) do
table.insert(newTb, v)
end
if #tb2 > 0 then
for i,v in pairs(tb2) do
table.insert(newTb, v)
end
end
return newTb
end
function TableUtil.print(tb)
for i, v in ipairs(tb) do
print(v.hua.." "..v.dian)
if i == #tb then print("=========")
else print("---") end
end
end
function TableUtil.sort(tb, comps)
local function defaultComps(a,b)
return a.dian < b.dian
end
if not comps then
comps = defaultComps
end
table.sort(tb, comps)
end
function TableUtil.uniqueConcat(tb1, tb2)
for i,v1 in pairs(tb2) do
local hasElement = false
for _, v2 in pairs(tb1) do
if v2.dian == v1.dian then
hasElement = true
break
end
end
if not hasElement then
table.insert(tb1, v1)
end
end
return tb1
end
CardDealer.lua
-- Author: luyuejun
-- Date: 2017/6/15
require("CardUtil")
CardDealer = {
cardStates = {
}
}
CardDealer.__index = CardDealer
function CardDealer:new()
local o = {}
setmetatable(o, self)
return o
end
function CardDealer:reset()
self.cardStates = {}
end
function CardDealer:dealTwoHands()
local cards = {}
--math.randomseed(tostring(os.time()):reverse():sub(1, 6))
while #cards < 2 do
local suit = math.random(1, 4)
local rank = math.random(1, 13)
local str = tostring(suit)..tostring(rank)
-- print("suit=",suit)
-- print("rank=",rank)
-- print("str=",str)
if self.cardStates[str] == nil then
self.cardStates[str] = true
local isHand = true
local card = Card:new(suit, rank, isHand)
table.insert(cards, card)
-- print("insert str=",str)
end
end
return cards
end
function CardDealer:dealPublic(amount)
if amount < 0 or amount > 5 then
print("CardDealer:dealPublic#amount error!")
return
else
local cards = {}
--math.randomseed(tostring(os.time()):reverse():sub(1, 6))
while #cards < amount do
local suit = math.random(1, 4)
local rank = math.random(1, 13)
local str = tostring(suit)..tostring(rank)
-- print("suit=",suit)
-- print("rank=",rank)
--print("str=",str)
if self.cardStates[str] == nil then
self.cardStates[str] = true
local isHand = false
local card = Card:new(suit, rank, isHand)
table.insert(cards, card)
end
end
return cards
end
end