php利用队列解决迷宫问题

<?php

# php利用队列解决迷宫问题
# 思路:从一个节点开始,寻找所有下面能继续走的点。继续寻找,直到找到出口。 -- 广度优先搜索
# 方法:创建一个空队列,将起点位置进队。在队列不为空时循环:出队一次。如果当前位置为出口,则结束算法;否则找出当前方块的4个相邻方块中可走的方块,全部进队。
# 迷宫
$maze = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];

# 获取节点的四个方向
function get_direction($x, $y)
{
    return [
        [$x - 1, $y], #上
        [$x, $y + 1], #右
        [$x + 1, $y], #下
        [$x, $y - 1], #左
    ];
}

function maze_path_queue($x1, $y1, $x2, $y2, $maze)
{
    $queue = []; #创建队列
    $path = [];    # 记录出队之后的节点
    array_push($queue, [$x1, $y1, -1]);
    $maze[$x1][$y1] = 2; #2表示已经走过的点
    while (count($queue) > 0) {
        $cur_node = array_shift($queue); # 出队列获取当前节点
        array_push($path, $cur_node);
        if ($cur_node[0] == $x2 && $cur_node[1] == $y2) { # 终点
            $real_path = [];
            $end_path = end($path);
            array_push($real_path, [$end_path[0], $end_path[1]]);#将终点坐标push到real_path中
            $i = $end_path[2];
            while ($i >= 0) {
                $node = $path[$i]; #node是一个元祖(x坐标,y坐标,该点的leader)
                array_push($real_path, [$node[0], $node[1]]); #只要坐标
                $i = $node[2];
            }
            $real_path = array_reverse($real_path); #反转后顺序才为从起点到终点
            foreach ($real_path as $v) {
                echo implode(',', $v) . "\n";
            }
            # print_r($real_path);
            return True;
        }

        $direction = get_direction($cur_node[0], $cur_node[1]);    #获取当前坐标的四个方向
        $i = 0;
        while ($i < 4) {
            $next_node = $direction[$i];            #下一个节点,循环四个方向是否可以走
            if ($maze[$next_node[0]][$next_node[1]] == 0) {        #如果下一个节点可以走 就将坐标存入队列
                array_push($queue, [$next_node[0], $next_node[1], (count($path) - 1)]); #(x坐标,y坐标,path最后一个元素的索引:记录哪个节点带它来的)进入队列
                $maze[$next_node[0]][$next_node[1]] = 2;            #标记为已经走过
            }
            $i++;
        }
    }

    print("无路可走");
    return False;
}

maze_path_queue(1, 1, 8, 8, $maze);


在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值