第一个参数传入手牌值,每张牌的0xXY,X代表花色(0-3),Y代表值(A-K),还有大小王。第二个参数传癞子数量。癞子可以当任意牌使用。手牌无癞子则传0.
function getTongHuaShunCardData(tabHandCardData,anyCount)
local checkCount = 5
local findTongHuaShun = function()
local countNum = {{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}},{0,{}}}
local cardCount = #tabHandCardData
for i=1,cardCount do
local cardData = tabHandCardData[i]
local cardValue = bit.band(cardData,0x0f)
countNum[cardValue][1] = countNum[cardValue][1] + 1
table.insert(countNum[cardValue][2],cardData)
end
local sameCardDataArr = {}
for _,v in ipairs({1,2,3,4,5,6,7,8,9,10}) do
local isTongShun = 0
local arr = {}
for i=1,checkCount - anyCount do
local cardValue = v+i-1
if cardValue==14 then
cardValue = 1
end
if countNum[cardValue][1]>=1 then
isTongShun = isTongShun + 1
end
table.insert(arr,cardValue)
end
if isTongShun>=(checkCount-anyCount) then
for _,color in ipairs({0x00,0x10,0x20,0x30}) do
local oderSame = true
for _,v in ipairs(arr) do
local isSameColor = false
for _,cardData in ipairs(countNum[v][2]) do
local cardColor = bit.band(cardData,0xf0)
if cardColor==color then
isSameColor = true
end
end
oderSame = oderSame and isSameColor
end
if oderSame then
table.insert(sameCardDataArr,bit.bor(color,arr[1]))
end
end
end
end
return sameCardDataArr
end
return findTongHuaShun()
end
返回同花顺的第一张牌的下标。
测试用例:
getTongHuaShunCardData({0x01,0x02,0x03,0x04,0x05,0x06,0x21,0x22,0x23,0x24,0x25,0x33,0x43},1) --手牌,癞子数
2018.6.21更新C++版本:
enum {
MEIHUA =0x00,
HONGTAO=0x10,
FANGKUAI=0x20,
HEITAO=0x30,
JOKER=0x40,
LAIZI =0x50
};
enum {
CARD_A = 0x01,
CARD_2 = 0x02,
CARD_3 = 0x03,
CARD_4 = 0x04,
CARD_5 = 0x05,
CARD_6 = 0x06,
CARD_7 = 0x07,
CARD_8 = 0x08,
CARD_9 = 0x09,
CARD_10 = 0x0a,
CARD_J = 0x0b,
CARD_Q = 0x0c,
CARD_K = 0x0d,
CARD_SMALL_JOKER = 0x0e,
CARD_BIG_JOKER = 0x0f,
};
map<int, map<int, map<int, int>>> ttt(const vector<int>&vecCardValue) {
map<int, vector<int>>mCard;
for (auto card:vecCardValue) {
switch (card&0xf0)
{
case MEIHUA:
cout << "meihua" << endl;
mCard[MEIHUA].push_back(card);
break;
case HONGTAO:
mCard[HONGTAO].push_back(card);
break;
case HEITAO:
mCard[HEITAO].push_back(card);
break;
case FANGKUAI:
mCard[FANGKUAI].push_back(card);
break;
case JOKER:
mCard[JOKER].push_back(card);
break;
case LAIZI:
mCard[LAIZI].push_back(card);
break;
default:
break;
}
}
//单一花色中
map<int, map<int, map<int, int>>> singleColor;
for (auto i=mCard.begin(); i != mCard.end(); ++i) {
map<int, int> tmpVec;
sort(i->second.begin(),i->second.end());
for (auto card : i->second) {
tmpVec[card & 0x0f] += 1;
}
//对某个值的牌
map<int, map<int, int>>result;
for (auto it = tmpVec.begin();it!=tmpVec.end();++it)
{
map<int, int>ivec = {};
ivec[it->first] += 1;
auto iter = it;
for (iter;iter!=tmpVec.end();++iter)
{
if (iter->first > it->first&&iter->first < it->first + 5) {
ivec[iter->first] += 1;
}
//cout << it->first << endl;
}
if (it->first > CARD_10&&it->first <= CARD_K) {
if (tmpVec[CARD_A]) {
ivec[CARD_A] += 1;
}
}
result[it->first] = ivec;
}
singleColor[i->first] = result;
}
return singleColor;
}
上述可以返回手牌中每一张牌其能组成的最大顺子(最大长度为5,如梅花2,3,4,5,6)。
测试用例如下:
int main() {
vector<int>vecCard = { 0x03,0x04,0x05,0x05,0x06,0x05,
0x07,0x09,0x09,0x0a,0x0b,0x0c,0x01,
0x14,0x15,0x20,0x35,0x42 };
map<int, map<int, map<int, int>>> singleColor = ttt(vecCard);
for (auto i = singleColor.begin(); i != singleColor.end(); ++i) {
auto mColor = i->second;
for (auto j = mColor.begin(); j != mColor.end(); ++j) {
auto card = j->first^i->first;
cout <<card<<":"<< j->second.size() << endl;
}
}
return 0;
}
输出如下,冒号后面值小于5的,都可以加上癞子牌来凑成5张组成同花顺。