"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bfsBlocks = bfsBlocks;
exports.linspace = linspace;
const vector_js_1 = require("./vector.js");
/**
 * BFS 遍历方块
 * @param startBlock 起始方块
 * @param condition 判断方块是否满足条件
 * @param maxDistance 可选，最大遍历距离
 */
function bfsBlocks(startBlock, condition, maxDistance = 20, maxBlocks = 64) {
    const visited = new Set();
    const queue = [
        { block: startBlock, distance: 0 },
    ];
    const result = [];
    while (queue.length > 0) {
        const { block, distance } = queue.shift();
        const locStr = vector_js_1.Vector3Utils.toString(block.location);
        if (visited.has(locStr))
            continue;
        visited.add(locStr);
        // 仅当方块满足条件时才加入结果并继续扩展邻居
        if (condition(block, distance)) {
            result.push(block);
            // 达到最大方块数则直接返回
            if (result.length >= maxBlocks)
                break;
            if (distance < maxDistance) {
                for (const neighbor of getNeighborBlocks(block)) {
                    if (result.length >= maxBlocks)
                        break; // 避免继续加入
                    const neighborLocStr = vector_js_1.Vector3Utils.toString(neighbor.location);
                    if (!visited.has(neighborLocStr)) {
                        queue.push({ block: neighbor, distance: distance + 1 });
                    }
                }
            }
        }
    }
    return result;
}
/**获取相邻方块 */
function getNeighborBlocks(block, corner = false) {
    const neighbors = [];
    // 正交方向
    const directions = [
        { x: 0, y: 1, z: 0 },
        { x: 0, y: -1, z: 0 },
        { x: 1, y: 0, z: 0 },
        { x: -1, y: 0, z: 0 },
        { x: 0, y: 0, z: 1 },
        { x: 0, y: 0, z: -1 },
    ];
    for (const dir of directions) {
        const nb = block.offset(dir);
        if (nb)
            neighbors.push(nb);
    }
    // 对角方向
    if (corner) {
        for (let dx of [-1, 0, 1]) {
            for (let dy of [-1, 0, 1]) {
                for (let dz of [-1, 0, 1]) {
                    if (dx === 0 && dy === 0 && dz === 0)
                        continue; // 自己
                    if (Math.abs(dx) + Math.abs(dy) + Math.abs(dz) === 1)
                        continue;
                    const nb = block.offset({ x: dx, y: dy, z: dz });
                    if (nb)
                        neighbors.push(nb);
                }
            }
        }
    }
    return neighbors;
}
/** 线性插值 */
function linspace(start, end, num) {
    if (num <= 0)
        return [];
    if (num === 1)
        return [start];
    const step = {
        x: (end.x - start.x) / (num - 1),
        y: (end.y - start.y) / (num - 1),
        z: (end.z - start.z) / (num - 1),
    };
    return Array.from({ length: num }, (_, i) => ({
        x: start.x + i * step.x,
        y: start.y + i * step.y,
        z: start.z + i * step.z,
    }));
}
