You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PHP多数组的游戏地图路径寻路算法实现问询

如何在游戏的地点网络中实现路径寻路算法?

看起来你需要在一个无权重的地点图中找到两点之间的路径,最适合这种场景的是**广度优先搜索(BFS)**算法——它不仅容易实现,还能保证找到起点到终点的最短路径(因为每个地点间的移动代价相同)。

先给你理清楚思路,再结合你的$location数组给出具体实现:

核心思路:BFS寻路

BFS的工作方式就像从起点“扩散”出去,逐层访问所有相邻的地点,同时记录每个地点是从哪个节点过来的(前置节点)。当我们找到终点时,就可以通过回溯前置节点,从终点倒推回起点,再反转得到正序的路径。

PHP实现代码

// 你的地点关联数组
$location = [
    1 => [1,2,3,4,5,6,7],
    2 => [1,3,7],
    3 => [1,2,4,11],
    4 => [1,3,5],
    5 => [1,4,6,16],
    6 => [1,5,17],
    7 => [1,2,23],
    8 => [9,10,11],
    9 => [8,10,11],
    10 => [8,9,11],
    11 => [8,9,10,3],
    12 => [13,14,16],
    13 => [12,14],
    14 => [12,13,16],
    15 => [16],
    16 => [12,14,5],
    17 => [18,20,6],
    18 => [17,19],
    19 => [18],
    20 => [17],
    21 => [22,23],
    22 => [21,23],
    23 => [21,22,7],
];

function findShortestPath($location, $start, $end) {
    // 处理起点就是终点的情况
    if ($start === $end) {
        return [$start];
    }

    // 队列:用于存储待访问的节点
    $queue = new SplQueue();
    $queue->enqueue($start);

    // 已访问节点:避免重复遍历
    $visited = [$start => true];

    // 前置节点记录:key是当前节点,value是到达它的上一个节点
    $prev = [];

    while (!$queue->isEmpty()) {
        $current = $queue->dequeue();

        // 遍历当前节点的所有关联地点
        foreach ($location[$current] as $neighbor) {
            if (!isset($visited[$neighbor])) {
                $visited[$neighbor] = true;
                $prev[$neighbor] = $current;
                $queue->enqueue($neighbor);

                // 找到终点,提前退出循环
                if ($neighbor === $end) {
                    $queue = new SplQueue(); // 清空队列结束循环
                    break;
                }
            }
        }
    }

    // 如果终点没有被访问到,说明没有路径
    if (!isset($prev[$end])) {
        return null;
    }

    // 回溯路径:从终点倒推回起点
    $path = [];
    $current = $end;
    while (isset($prev[$current])) {
        array_unshift($path, $current);
        $current = $prev[$current];
    }
    array_unshift($path, $start);

    return $path;
}

// 测试:从地点1到地点8
$path = findShortestPath($location, 1, 8);
if ($path) {
    echo "找到路径:" . implode(' -> ', $path);
    // 输出:找到路径:1 -> 3 -> 11 -> 8
} else {
    echo "没有可用路径";
}

其他可选方案

  • 深度优先搜索(DFS):如果你需要探索所有可能的路径(而不是最短路径),可以用DFS,但它不能保证找到最短路径,适合需要遍历所有路线的场景。
  • Dijkstra算法:如果以后你的游戏给不同路径添加了权重(比如某些路线消耗更多体力/时间),Dijkstra算法可以找到权重最小的路径,是BFS的加权版本。

注意事项

  • 你的$location数组中,部分节点包含自身(比如$location[1]里有1),在遍历的时候其实可以跳过自身,避免无效的循环访问,上面的代码已经通过visited数组自动处理了这种情况,但你也可以在遍历前先过滤掉自身节点优化性能。
  • 如果你的地图很大,可以考虑优化队列和访问数组的存储方式,不过对于当前的规模来说,上面的实现完全够用。

内容的提问来源于stack exchange,提问作者Eddas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:05