COCOS LUA 四川麻将胡牌算法讲解 附带源代码

房卡棋牌游戏正如火如荼的遍地开花,迫使我也加入开发中的一员,最近完成了一套麻将棋牌游戏!今天给大家分享一下其中的算法部分!更多房卡棋牌游戏技术,会陆续分享!!!转载请说明出处!
博客链接地址:http://blog.csdn.net/weixin_41082095/article/details/79258241

LUA源代码下载

一副麻将是否能胡牌就必须满足以下公式(特殊牌型出外,7对,龙七对)
N*AAA+N*ABC+1*AA
看懂了吗?如果一副牌由N个刻子,N个连牌,有且只有一对将牌组成!那么我们就可以认为这副牌胡了!
如果还没有搞懂没关系,下面我们依次讲解什么意思!

AAA ABC AA
AAA:刻子 3张花色一样,点数一样的牌,俗称一砍牌
ABC:连牌 3张花色一样,点数彼此相差一点 如:123 345 678 俗称一搭牌
AA:对子 2张花色一样,点数一样的牌,俗称麻将


可以回忆一下我们平时打麻将胡牌之后牌型是否都满足这样的公式。
现在我们知道了胡牌的公式,那么在程序语言中我们是怎么来计算的呢????
工欲善其事,必先利其器!!!首先我们来定义一个麻将的数据结构
我们知道一副麻将里面有3种花色(万,筒,条),9个点数(1----9),我们就可以定义一个三维数组来存储我们手牌

Local handCard=
{
{0,0,0,0,0,0,0,0,0}, --表示万
{0,0,0,0,0,0,0,0,0}, --表示筒
{0,0,0,0,0,0,0,0,0} --表示条
}
如图:

这副牌在数组里面就可以这样来定义
Local handCard=
{
{1,2,1,0,1,0,2,0,0}, --表示万
{0,0,1,1,1,0,2,0,1}, --表示筒
{0,0,0,0,0,0,0,0,0} --表示条
}
看懂了嚒,每一个值代表每一张牌出现了几次,我们还可以在handCard里面再多定义一个数组用来表示每一张牌的属性,方便我们后面来计算连牌
 handCard[4]={}
for i=1,3 do
for j=1,9 do
for h=1,card[i][j] do
local cardData ={}
cardData.color = i
cardData.point = j
card[4][#card[4]+1]= cardData
end
end
end


这样我们手牌牌如何用数据来表示就完成了,接下来我们就可以开始拆牌了。定义几个数组分别用来储存 同一张牌出现了4次的牌,3次的牌,2次的牌。
 local cardData={}
self.twoCardAry={}
self.threeCardAry={}
self.fourCardAry={}
self.cloneCardList = {}

for i=1, 3 do
for j=1,9 do
cardData={}
if tempCardList[i][j] == 2 then
cardData.color = i
cardData.point = j
self.twoCardAry[#self.twoCardAry+1] = cardData
elseif tempCardList[i][j] == 3 then
cardData.color = i
cardData.point = j
self.threeCardAry[#self.threeCardAry+1] = cardData
elseif tempCardList[i][j] == 4 then
cardData.color = i
cardData.point = j
self.fourCardAry[#self.fourCardAry+1] = cardData
end
end
end

最后依次把每张牌能组成的牌型都遍历一次,看最后能否满足我们之前定义的胡牌公式。
---是否能胡牌 参数 1牌的列表 2 打的那张牌 3自己缺的花色
function Algorithm:PlayerIs_Hu(cardList,nSendCardValue,nQueSe)

local tempCardList = {}
tempCardList[4]={}
for i=1,3 do
tempCardList[i]={}
for j=1,9 do
tempCardList[i][j] = cardList[i][j]
end
end
tempCardList[nSendCardValue.color][nSendCardValue.point] = tempCardList[nSendCardValue.color][nSendCardValue.point] + 1
self:SortPlayerCards(tempCardList)

--判断自己缺的花色打完没有
for i=1,9 do
if tempCardList[nQueSe][i]>0 then return false end
end

local cardData={}
self.twoCardAry={}
self.threeCardAry={}
self.fourCardAry={}
self.cloneCardList = {}

for i=1, 3 do
for j=1,9 do
cardData={}
if tempCardList[i][j] == 2 then
cardData.color = i
cardData.point = j
self.twoCardAry[#self.twoCardAry+1] = cardData
elseif tempCardList[i][j] == 3 then
cardData.color = i
cardData.point = j
self.threeCardAry[#self.threeCardAry+1] = cardData
elseif tempCardList[i][j] == 4 then
cardData.color = i
cardData.point = j
self.fourCardAry[#self.fourCardAry+1] = cardData
end
end
end

if #self.twoCardAry == 7 then return true end --7对
if #self.twoCardAry == 5 and #self.fourCardAry ==1 then return true end --龙七对

local tempFour = 0
local tempThree = 0
local tempTwo = 0

if next(self.twoCardAry)~=nil then tempTwo = #self.twoCardAry end
if next(self.threeCardAry)~=nil then tempThree = #self.threeCardAry end
if next(self.fourCardAry)~=nil then tempFour = #self.fourCardAry end


--要胡牌 必须满足 AAA ABC AA 必须要有一对将牌
local isHuCard = false
for i=0,tempFour do
for j=0,tempThree do
for k=0,tempTwo do
self.cloneCardList ={}

for g=1,#tempCardList[4] do
self.cloneCardList[g] = tempCardList[4][g]
end

isHuCard = self:CalcIsHuCard(i,j,k)
if isHuCard == true then return true end
end
end
end

return false
end


function Algorithm:CalcIsHuCard(nFourIndex,nThreeIndex,nTwoIndex)

local FourCardData = nil
local ThreeCardData = nil
local TwoCardData = nil

if nFourIndex>0 then FourCardData = self.fourCardAry[nFourIndex] end
if nThreeIndex>0 then ThreeCardData = self.threeCardAry[nThreeIndex] end
if nTwoIndex>0 then TwoCardData = self.twoCardAry[nTwoIndex] end

self:DelCardOfCardList(self.cloneCardList,FourCardData,4)
self:DelCardOfCardList(self.cloneCardList,ThreeCardData,3)
self:DelCardOfCardList(self.cloneCardList,TwoCardData,2)

--剔除所有的连牌
local nCntIndex = #self.cloneCardList

local i=1
local j=1
local h=1
while i<=nCntIndex do
j=i+1
while j<=nCntIndex do
h=j+1
while h<=nCntIndex do
if self.cloneCardList[i].color == self.cloneCardList[j].color and self.cloneCardList[i].color == self.cloneCardList[h].color
and self.cloneCardList[i].point+1 == self.cloneCardList[j].point and self.cloneCardList[j].point+1 == self.cloneCardList[h].point then
local card1 = self.cloneCardList[i]
local card2 = self.cloneCardList[j]
local card3 = self.cloneCardList[h]

self:DelCardOfCardList(self.cloneCardList,card1,1)
self:DelCardOfCardList(self.cloneCardList,card2,1)
self:DelCardOfCardList(self.cloneCardList,card3,1)

nCntIndex = #self.cloneCardList
i=1 j=2 h=3
else
h=h+1
end
end
j=j+1
end
i=i+1
end

if nTwoIndex>0 then --如果有一对 剩余的牌必须为0 才能胡牌
if nCntIndex == 0 then
return true
end
else ---如果没有一对 最后必须没有单牌 和有且只有一对
local twoAry={}
local OneAry={}
local cardAry={}
for i=1,3 do
cardAry[i]={}
for j=1,9 do
cardAry[i][j]=0
end
end

for i=1,nCntIndex do
local data = self.cloneCardList[i]
cardAry[data.color][data.point] = cardAry[data.color][data.point] + 1
end


local nIndex = 1
for i=1,3 do
for j=1,9 do
if cardAry[i][j]==1 then
return false
elseif cardAry[i][j]==2 then
nIndex = nIndex +1
if nIndex == 3 then
return false
end
end
end
end


return true

end


return false
end
...全文
3544 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
BaguvixMe 2020-08-08
  • 打赏
  • 举报
回复
一般客户端这边需要自己先捋一遍是否能出这些判断再发,要不然会有点延迟
卡特拉 2019-09-01
  • 打赏
  • 举报
回复
引用 2 楼 文修 的回复:
perfect ,不过房卡游戏算法一般是在服务端实现,客户端只需要负责显示就可以了,而且麻将的算法如果放在客户端,就会显得没有可读性
你问破译这个软件吗
文修 2018-04-17
  • 打赏
  • 举报
回复
perfect ,不过房卡游戏算法一般是在服务端实现,客户端只需要负责显示就可以了,而且麻将的算法如果放在客户端,就会显得没有可读性
playonemore 2018-04-12
  • 打赏
  • 举报
回复
不错好帖子,值得学习下

721

社区成员

发帖
与我相关
我的任务
社区描述
Cocos2d-x相关内容讨论专区
社区管理员
  • Cocos2d-x
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧