GameLogic = {}
local MAX_CARD_NUM = 14
function GameLogic:new (o)
o = o or {}
setmetatable(o, self)
self.__index = self
self:init()
return o
end
function printTable(tab)
local logs = ‘’;
for k,v in ipairs(tab) do
logs = logs…v…’,’
end
return logs
end
function removeArray(v,arr)
local a = {}
local first = true
for i, j in pairs(arr) do
if j == v and first then
first = false
else
table.insert(a,j)
end
end
return a;
end
function insertArray(v,arr)
table.insert(arr,v);
local sort = function(a,b)
return b>a;
end
table.sort(arr,sort);
return arr;
end
function copyArray(arr)
local a = {}
for i, j in pairs(arr) do
table.insert(a,j)
end
return a;
end
function GameLogic:init()
self.numLaiZi = 1
self.searchPath = ‘’
end
function GameLogic:calc(cards)
local mj = {}
self.numLaiZi = 0
local wans = {}
local tongs = {}
local tiaos = {}
for i, v in pairs(cards) do
if v ~= 35 then
if v < 10 then
table.insert(wans,v)
elseif v < 20 then
table.insert(tongs,v)
elseif v < 30 then
table.insert(tiaos,v)
end
else
self.numLaiZi = self.numLaiZi+1;
end
end
print('牌局分析结果: '..self.numLaiZi..'个赖子,'..#wans..'个万子,'..#tongs..'个筒子,'..#tiaos..'个条子')
self.needMinHunNum = 14;
self:getMinLaiZi(wans,0,'')
self.numWanMinHum = self.needMinHunNum
self.needMinHunNum = MAX_CARD_NUM;
self:getMinLaiZi(tongs,0,'')
self.numTongMinHum = self.needMinHunNum
self.needMinHunNum = MAX_CARD_NUM;
self:getMinLaiZi(tiaos,0,'')
self.numTiaoMinHum = self.needMinHunNum
self.needMinHunNum = MAX_CARD_NUM;
print('胡牌所需要的赖子数: 万子:'..self.numWanMinHum..',筒子:'..self.numTongMinHum..',条子:'..self.numTiaoMinHum)--]]
local wanLaiZi = self.numLaiZi-(self.numTongMinHum+self.numTiaoMinHum)
if wanLaiZi >= 0 then
local resWan = self:canJiangHu(copyArray(wans),wanLaiZi);
if resWan then
print('resTong:万子作将可胡牌:',self.searchPath)
return true;
end
end
local tongLaiZi = self.numLaiZi-(self.numWanMinHum+self.numTiaoMinHum)
if tongLaiZi >= 0 then
local resTong = self:canJiangHu(copyArray(tongs),tongLaiZi);
if resTong then
print('resTong:筒子作将可胡牌',self.searchPath)
return true;
end
end
local tiaoLaiZi = self.numLaiZi-(self.numWanMinHum+self.numTongMinHum)
if tiaoLaiZi >= 0 then
local resTiao = self:canJiangHu(copyArray(tiaos),tiaoLaiZi);
if resTiao then
print('resTong:条子作将可胡牌:',self.searchPath)
return true;
end
end
return false
end
function GameLogic:getMinLaiZi(cards,needNum,logs)
self.needMinHunNum = self.needMinHunNum or 14
if self.needMinHunNum == 0 then
return
end
if needNum > self.numLaiZi then
return --没有那么多赖子
end
local lastNum = self.needMinHunNum
local len = #cards
if len == 0 then
self.needMinHunNum = math.min(needNum,self.needMinHunNum)
if self.needMinHunNum < lastNum then
self.searchPath = logs;
end
return
elseif len == 1 then
self.needMinHunNum = math.min(needNum+2,self.needMinHunNum)
if self.needMinHunNum < lastNum then
self.searchPath = logs;
end
return
elseif len == 2 then
local c1 = cards[1];
local c2 = cards[2];
if c2-c1 < 3 then
self.needMinHunNum = math.min(needNum+1,self.needMinHunNum)
end
if self.needMinHunNum < lastNum then
self.searchPath = logs;
end
return
end
local p1 = cards[1];
local p2 = cards[2];
local p3 = cards[3];
if needNum+2<self.needMinHunNum then
cards = removeArray(p1,cards);
logs = logs..p1..','
self:getMinLaiZi(cards,needNum+2,logs);
cards = insertArray(p1,cards);
local l = 1
if p1 > 10 then l = 2 end
logs = string.sub(logs,0,string.len(logs)-1-l)
end
if (needNum + 1<self.needMinHunNum) then
for i=2, len do
if needNum+1 < self.needMinHunNum then
p2 = cards[i];
local con = false
if i+1 <= len then
p3 = cards[i+1];
if p3 == p2 then
con = true
end
end
if con == false and p2 - p1 < 3 then
cards = removeArray(p1,cards);
cards = removeArray(p2,cards);
logs = logs..p1..p2..','
self:getMinLaiZi(cards,needNum+1,logs);
cards = insertArray(p2,cards)
cards = insertArray(p1,cards);
local l = 1
if p1 > 10 then l = 2 end;
logs = string.sub(logs,0,string.len(logs)-2*l-1)
end
end
end
end
for i=2, len do
if (needNum < self.needMinHunNum) then
p2 = cards[i];
local con = false
if i+2 <= len then
if cards[i+2] == p2 then
con = true;
end
end
if con == false then
for j=i+1,len do
local con1 = false;
if (needNum >= self.needMinHunNum) then
break;
end
p3 = cards[j]
if j+1 <= len then
if p3 == cards[j+1] then
con1 = true
end
end
if con1 == false then
if p3 + p1 == p2*2 and p2-p1 <= 1 then -- 验证 123 和 111
cards = removeArray(p1,cards);
cards = removeArray(p2,cards);
cards = removeArray(p3,cards);
logs = logs..p1..p2..p3..','
self:getMinLaiZi(cards,needNum,logs);
cards = insertArray(p3,cards);
cards = insertArray(p2,cards);
cards = insertArray(p1,cards);
local l = 1
if p1 > 10 then l = 2 end;
logs = string.sub(logs,0,string.len(logs)-3*l-1)
end
end
end
end
end
end
end
function GameLogic:canJiangHu(cards,numHu)
local len = #cards
if len == 0 then
if needNum == 2 then – 鬼吊的情况
return 35
end
end
local copyCards = copyArray(cards);
for i,v in ipairs(copyCards) do
if i == len then
if numHu > 0 then
numHu = numHu - 1
cards = removeArray(v,cards)
self.needMinHunNum = MAX_CARD_NUM
self:getMinLaiZi(cards,0,v…’,’);
if self.needMinHunNum <= numHu then
return v;
end
numHu = numHu + 1
cards = insertArray(v,cards);
end
else
if i+2 == len or v ~= copyCards[i+2] then
if copyCards[i+1] == v then
cards = removeArray(v,cards)
cards = removeArray(copyCards[i+1],cards)
self:getMinLaiZi(cards,0,v…copyCards[i+1]…’,’);
if self.needMinHunNum <= numHu then
return v;
end
cards = insertArray(v,cards);
cards = insertArray(copyCards[i+1],cards);
end
end
if numHu > 0 and v ~= copyCards[i+1] then
numHu = numHu - 1
cards = removeArray(v,cards)
self.needMinHunNum = MAX_CARD_NUM
self:getMinLaiZi(cards,0,v..',');
if self.needMinHunNum <= numHu then
return v;
end
numHu = numHu + 1
cards = insertArray(v,cards);
end
end
end
return nil
end
return GameLogic