c1_lua/lua/app/module/battle/helper/board_helper.lua
2023-06-29 21:56:47 +08:00

172 lines
6.0 KiB
Lua

local BoardHelper = {}
local BattleConst = GConst.BattleConst
function BoardHelper:getEmptyTable()
if not self.tempEmptyTables then
self.tempEmptyTables = {}
end
if not self.tempEmptyTables[1] then
table.insert(self.tempEmptyTables, {})
end
return table.remove(self.tempEmptyTables)
end
function BoardHelper:recycleedEmptyTable(emptyTable)
if not emptyTable then
return
end
emptyTable = table.clear(emptyTable)
if self.tempEmptyTables then
table.insert(self.tempEmptyTables, emptyTable)
end
end
function BoardHelper:findPvpLinkOptimalSolution(battleController, startRow, endRow, elementTypeCoefficient)
local battleData = battleController.battleData
local gridMap = BoardHelper:getEmptyTable()
local gridEntities = BoardHelper:getEmptyTable()
local step = 1
if startRow > endRow then
step = -1
end
for row = startRow, endRow, step do -- 遍历所有的可使用格子
for column = 1, BattleConst.COLUMN_COUNT do
local posId = ModuleManager.BattleManager:getPosId(row, column)
local gridEntity = battleData:getGridEnties()[posId]
if gridEntity and gridEntity:canLink() then
table.insert(gridEntities, posId)
gridMap[posId] = gridEntity
end
end
end
local maxPath
local maxPathCount = 0
local newHaveSkill = false
local lastMainElementType
if not elementTypeCoefficient then
elementTypeCoefficient = BoardHelper:getEmptyTable()
end
for _, posId in pairs(gridEntities) do
local entity = gridMap[posId]
local mainElementType
if not entity:getSkillId() then
mainElementType = entity:getElementType()
local tree = BoardHelper:getEmptyTable()
self:getCanlinkTree(posId, gridMap, tree, mainElementType)
local checked = BoardHelper:getEmptyTable()
local haveSkill = false
local path, getSkill = self:findMaxPath(posId, tree, checked, haveSkill, gridMap)
local count = #path
if getSkill and not newHaveSkill then
maxPath = path
maxPathCount = count
newHaveSkill = getSkill
lastMainElementType = mainElementType
else
local curCoefficient = elementTypeCoefficient[mainElementType] or 0
local lastCoefficient = elementTypeCoefficient[lastMainElementType] or 0
if not getSkill and newHaveSkill then
BoardHelper:recycleedEmptyTable(path)
else
if count * curCoefficient > maxPathCount * lastCoefficient then
maxPath = path
maxPathCount = count
newHaveSkill = getSkill
lastMainElementType = mainElementType
else
BoardHelper:recycleedEmptyTable(path)
end
end
end
for posId, info in pairs(tree) do
BoardHelper:recycleedEmptyTable(info)
end
BoardHelper:recycleedEmptyTable(tree)
BoardHelper:recycleedEmptyTable(checked)
end
end
BoardHelper:recycleedEmptyTable(elementTypeCoefficient)
BoardHelper:recycleedEmptyTable(gridMap)
return maxPath
end
function BoardHelper:findMaxPath(posId, tree, checked, haveSkill, gridMap)
if not checked[posId] and tree[posId] then
local newPath
local newPathCount = 0
local newHaveSkill = false
local newChecked = GFunc.getTable(checked)
newChecked[posId] = true
for nextPosId, _ in pairs(tree[posId]) do
local entity = gridMap[nextPosId]
if not entity:getSkillId() or not haveSkill then
if entity:getSkillId() then
haveSkill = true
end
local p, getSkill = self:findMaxPath(nextPosId, tree, newChecked, haveSkill, gridMap)
if p then
local count = #p
if getSkill and not newHaveSkill then
newPath = GFunc.getTable(p)
newPathCount = count
newHaveSkill = getSkill
else
if not getSkill and newHaveSkill then
BoardHelper:recycleedEmptyTable(p)
else
if count > newPathCount then
newPath = GFunc.getTable(p)
newPathCount = count
newHaveSkill = getSkill
else
BoardHelper:recycleedEmptyTable(p)
end
end
end
end
end
end
if not newPath then
newPath = BoardHelper:getEmptyTable()
end
table.insert(newPath, 1, posId)
if not newHaveSkill then
newHaveSkill = gridMap[posId]:getSkillId() ~= nil
end
return newPath, newHaveSkill
end
end
function BoardHelper:getCanlinkTree(posId, gridMap, tree, mainElementType)
if tree[posId] then
return
end
local ids = self:getAroundPosIds(posId, gridMap, mainElementType)
tree[posId] = ids
for aroundPosId, status in pairs(ids) do
self:getCanlinkTree(aroundPosId, gridMap, tree, mainElementType)
end
end
function BoardHelper:getAroundPosIds(posId, gridMap, mainElementType)
local ids = BoardHelper:getEmptyTable()
local aroundPosIds = BattleConst.GRID_OUT_LINE_POS_ID[posId]
if aroundPosIds then
for id, status in pairs(aroundPosIds) do
if gridMap[id] and (gridMap[id]:getElementType() == mainElementType or gridMap[id]:getSkillId()) then
ids[id] = true
end
end
end
return ids
end
return BoardHelper