client3/lua_probject/main_project/main/zipai/CardCheck.lua

477 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

-- 检测牌是否存在
local function checkCard(eventCard, cardList, num)
if num == nil then
num = 1
end
local result = 0
for i = 1, #cardList do
if (cardList[i] == eventCard) then
result = result + 1
if (result == num) then
return true
end
end
end
return false
end
-- 移除指定数量的牌
local function removeCard(cardList, card, count)
for i = 1, count do
list_remove(cardList, card)
end
end
local function checkCardAndRomve(eventCard, cardList, num)
if (checkCard(eventCard, cardList, num)) then
removeCard(cardList, eventCard, num)
return true
end
return false
end
-- 获取列表中牌数量
local function cardNum(eventCard, cardList)
local result = 0
for i = 1, #cardList do
local card = cardList[i]
if (card == eventCard) then
result = result + 1
end
end
return result
end
local M = {
pair_count = 0,
cardList = nil,
stack = nil,
stackHuxi = nil
}
function M:push(cardGroup)
self.stack[#self.stack + 1] = cardGroup
end
function M:pushhuxi(cardGroup)
self.stackHuxi[#self.stackHuxi + 1] = cardGroup
end
function M:rollBack()
local cardGroup = self.stack[#self.stack]
table.remove(self.stack, #self.stack)
for _, card in ipairs(cardGroup) do
self.cardList[#self.cardList + 1] = card
end
table.sort(self.cardList)
end
-- 顺子
function M:tryShunzi1(card, player)
if card < 300 and card % 100 > 8 then
return false
end
if (checkCard(card + 1, self.cardList) and checkCard(card + 2, self.cardList)) then
removeCard(self.cardList, card + 1, 1)
removeCard(self.cardList, card + 2, 1)
removeCard(self.cardList, card, 1)
local cardGroup = {card, card + 1, card + 2}
self:push(cardGroup)
local _huxi = 0
if card == 101 then
_huxi = 3
end
if card == 201 then
_huxi = 6
end
self:pushhuxi(_huxi)
return true
end
return false
end
-- 大大小 小小大
function M:tryShunzi2(card)
if card - card % 100 == 100 then
if checkCard(card + 100, self.cardList, 1) and checkCard(card, self.cardList, 2) then
removeCard(self.cardList, card, 2)
removeCard(self.cardList, card + 100, 1)
local cardGroup = {card, card, card + 100}
self:push(cardGroup)
self:pushhuxi(0)
return true
end
if (checkCard(card + 100, self.cardList, 2)) and (checkCard(card, self.cardList, 1)) then
removeCard(self.cardList, card, 1)
removeCard(self.cardList, card + 100, 2)
local cardGroup = {card, card + 100, card + 100}
self:push(cardGroup)
self:pushhuxi(0)
return true
end
else
if (checkCard(card - 100, self.cardList, 1)) and checkCard(card, self.cardList, 2) then
removeCard(self.cardList, card, 2)
removeCard(self.cardList, card - 100, 1)
local cardGroup = {card - 100, card, card}
self:push(cardGroup)
self:pushhuxi(0)
return true
end
if (checkCard(card - 100, self.cardList, 2)) and checkCard(card, self.cardList, 1) then
removeCard(self.cardList, card, 1)
removeCard(self.cardList, card - 100, 2)
local cardGroup = {card, card - 100, card - 100}
self:push(cardGroup)
self:pushhuxi(0)
return true
end
end
--print(card)
return false
-- body
end
-- 2 7 10
function M:tryShunzi3(card, player)
if card % 100 == 2 then
if (checkCard(card + 5, self.cardList, 1)) and (checkCard(card + 8, self.cardList, 1)) then
removeCard(self.cardList, card, 1)
removeCard(self.cardList, card + 5, 1)
removeCard(self.cardList, card + 8, 1)
local cardGroup = {card, card + 5, card + 8}
self:push(cardGroup)
local _huxi = 0
if card == 102 then
_huxi = 3
elseif card == 202 then
_huxi = 6
end
self:pushhuxi(_huxi)
return true
end
end
return false
end
-- 坎
function M:tryKezi(card, player)
if (checkCard(card, self.cardList, 3)) then
removeCard(self.cardList, card, 3)
local cardGroup = {card, card, card}
self:push(cardGroup)
local _huxi = 0
if card < 200 then
_huxi = 1
else
_huxi = 3
end
self:pushhuxi(_huxi)
return true
end
-- print(card)
return false
end
function M:tryPair(card)
if (self.pair_count > 0) then
return false
end
if (checkCard(card, self.cardList, 2)) then
removeCard(self.cardList, card, 2)
local cardGroup = {card, card}
self:push(cardGroup)
self.pair_count = 1
return true
end
-- print(card)
return false
end
function M:tryWin(player)
if #self.cardList == 0 then
if (player.tiCount + player.paoCount + self.kong_count > 0) then
if (self.pair_count == 1) then
return true
end
return false
else
if (self.pair_count > 0) then return false end
return true -- 【这里允许了无将胡牌!】
end
end
local activeCard = 0
for i = 1, #self.cardList do
if (self.cardList[i] == 201 or self.cardList[i] == 202) then
activeCard = self.cardList[i]
break
end
end
if (activeCard == 0) then
activeCard = self.cardList[1]
end
if (activeCard % 100 == 1) then
if self:tryShunzi1(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if self:tryKezi(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if (player.tiCount + player.paoCount + self.kong_count > 0) then
if self:tryPair(activeCard) then
if self:tryWin(player) then
return true
end
self.pair_count = 0
self:rollBack()
end
end
if self:tryShunzi2(activeCard) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
elseif activeCard % 100 == 2 then
if self:tryShunzi3(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if self:tryKezi(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if player.tiCount + player.paoCount + self.kong_count > 0 then
if self:tryPair(activeCard) then
if self:tryWin(player) then
return true
end
self.pair_count = 0
self:rollBack()
end
end
if self:tryShunzi1(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if self:tryShunzi2(activeCard) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
else
if self:tryKezi(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if player.tiCount + player.paoCount + self.kong_count > 0 then
if self:tryPair(activeCard) then
if self:tryWin(player) then
return true
end
self.pair_count = 0
self:rollBack()
end
end
if self:tryShunzi2(activeCard) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
if self:tryShunzi1(activeCard, player) then
if self:tryWin(player) then
return true
end
self:rollBack()
table.remove(self.stackHuxi, #self.stackHuxi)
end
end
return false
end
local function init(self, player, cardInhand, addCard)
self.stack = {}
self.stackHuxi = {}
self.pair_count = 0
self.kong_count = 0
self.cardList = membe_clone(cardInhand)
if addCard == nil then
self.kong_count = 1
else
self.kong_count = 0
self.cardList[#self.cardList + 1] = addCard
end
table.sort(self.cardList)
return self:tryWin(player)
end
function M.tingPai(player, room)
local self = setmetatable({}, {__index = M})
local tingList = {}
-- 克隆手牌,保护原始数据
local cardInhand = membe_clone(player.handcard_list)
if not cardInhand or #cardInhand == 0 then
return tingList
end
local kan_huxi = 0
local kan_cards = {}
-- 计算坎牌胡息并移除
for j = 1, #player.fz_list do
for i = 1, #cardInhand do
if cardInhand[i] == player.fz_list[j].active_card and player.fz_list[j].type == 3 then
kan_cards[#kan_cards + 1] = cardInhand[i]
break
end
end
end
if #kan_cards > 0 then
for i = 1, #kan_cards do
if kan_cards[i] > 200 then
kan_huxi = kan_huxi + 6
else
kan_huxi = kan_huxi + 3
end
removeCard(cardInhand, kan_cards[i], 3)
end
end
-- 【重要】不要修改原始 player 对象,创建一个临时表用于 init 调用
local tempPlayer = {
tiCount = 0,
paoCount = 0,
hu_xi = player.hu_xi, -- 确保 hu_xi 被正确引用
fz_list = player.fz_list
}
if #player.fz_list > 0 then
for i = 1, #player.fz_list do
if player.fz_list[i].type == 6 then
tempPlayer.paoCount = tempPlayer.paoCount + 1
elseif player.fz_list[i].type == 7 then
tempPlayer.tiCount = tempPlayer.tiCount + 1
end
end
end
local minHuXi = self:getHuxi(room)
for k = 100, 200, 100 do
for i = 1, 10 do
local tem = k + i
-- 使用 tempPlayer 进行判断,避免污染全局 player
local result = init(self, tempPlayer, cardInhand, tem)
local num = 0
for k = 1, #self.stackHuxi do
num = num + self.stackHuxi[k]
end
local totalHuXi = (tempPlayer.hu_xi + num + kan_huxi)
local isZeroHuXiSpecial = (totalHuXi == 0)
-- 【核心修复】:必须首先保证牌型结构正确 (result == true)
if result then
-- 牌型正确的前提下,检查胡息
if (totalHuXi >= minHuXi) or isZeroHuXiSpecial then
tingList[#tingList + 1] = tem
end
else
-- 牌型结构不正确,尝试跑胡/补救逻辑
if #player.fz_list > 0 then
for k = 1, #player.fz_list do
if tem == player.fz_list[k].active_card then
local ctype = player.fz_list[k].type
if ctype == 2 or ctype == 3 or ctype == 4 or ctype == 5 then
-- 跑胡检测:不带 tem看剩余牌是否能胡靠张
local paohu = init(self, tempPlayer, cardInhand)
if paohu then
local num2 = 0
for j = 1, #self.stackHuxi do
num2 = num2 + self.stackHuxi[j]
end
-- 跑胡胡息计算
local runHuTotal = num2 + tempPlayer.hu_xi + kan_huxi + self:GetFzData(tem, ctype)
if runHuTotal >= minHuXi then
tingList[#tingList + 1] = tem
end
end
end
end
end
end
end
end
end
return tingList
end
function M:getHuxi(room)
if room.game_id == 301 then
return 8
end
if room.game_id == 15 then
return 15
end
if room.game_id == 16 then
return 10
end
if room.game_id == 17 then
return 15
end
if room.game_id == 13 or room.game_id == 14 or room.game_id == 23 then
return 15
elseif room.game_id == 26 then
return 10
elseif room.game_id == 29 then
if room.room_config.maxPlayers == 3 then
return 15
else
return 9
end
else
return 15
end
end
function M:GetFzData(tem, ctype)
local huxi
if ctype == 2 then
if tem > 200 then
huxi = 6
else
huxi = 5
end
elseif ctype == 3 then
huxi = 3
elseif ctype == 4 then
huxi = 3
elseif ctype == 5 then
huxi = 3
end
return huxi
end
return M