--- 获取不同象限的X循环范围 localfunctionCalculateXRange(directions, x, width) local rightFactor = directions[1][1] return x, x + width * rightFactor - 1, rightFactor end
--- 获取不同象限的Y循环范围 localfunctionCalculateYRange(directions, y, height) local upFactor = directions[4][2] return y, y + height * upFactor - 1, upFactor end
--- 根据方向、起始位置、占地面积循环遍历 --- @param action fun(i: number, j: number) localfunctionForEachRange(directions, x, y, width, height, action) local startX, targetX, widthFactor = CalculateXRange(directions, x, width) local startY, targetY, heightFactor = CalculateYRange(directions, y, height) for i = startX, targetX, widthFactor do for j = startY, targetY, heightFactor do action(i, j) end end end
--- 当前索引是否有效 localfunctionisValidIndex(grid, x, y) return x >= 1and x <= #grid and y >= 1and y <= #grid[x] end
--- 当前位置是否有效 localfunctionisValidArea(grid, directions, x, y, width, height) ifnot isValidIndex(grid, x, y) ornot isValidIndex(grid, x + width - 1, y + height - 1) then returnfalse end local result = true ForEachRange(directions, x, y, width, height, function(i, j) ifnot grid[i][j] then result = false end end) return result end
localfunctionSearch(grid, directions, queue, visited, width, height, startX, startY) local result = nil local baseScore = math.huge while #queue > 0do count = count + 1 local current = table.remove(queue, 1) local x, y, distance = current[1], current[2], current[3]
for index, direction inipairs(directions) do local newX = x + direction[1] local newY = y + direction[2] if isValidIndex(grid, newX, newY) andnot visited[newX][newY] then visited[newX][newY] = true table.insert(queue, { newX, newY, distance + 1 })
if isValidArea(grid, directions, newX, newY, width, height) then local score = EvaluateScore(index, startX, startY, newX, newY, width, height) if score < baseScore then baseScore = score result = { newX, newY } end end end end end return result end