栈-迷宫算法

小孩子经常玩过的一种游戏——走迷宫,我们也可以用算法来解决;

下面的方案只是针对迷宫找出一种走出迷宫的方案,并不是最优路径;

class Stack{
    private $stack = array();
    
    #检测是否为null
    public function stack_is_null()
    {
        if(count($this->stack) <= 0){
           return true;
        }
        return false;
    }
    
    #进栈
    public function push($value)
    {
        array_push($this->stack,$value);
    }

    #出栈
    public funtcion pop()
    {
        if($this->stack_is_null()){
            return null;
        }
        return array_pop($this->stack);
    }

    #取栈顶,取最后一个值
    public function get_top()
    {
        if($this->stack_is_null()){
            return null;
        }
        return end($this->stack);
    }

    #取栈顶,取最后一个值
    public function get_top()
    {
        if(this->stack_is_null()){
            return null;
        }
        return end($this->stack);
    }

    #返回栈内所有的元素
    public function get_stack(){
        return $this->stack;
    }
}
#模拟迷宫
$moze = [
	[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,1,0,1],
	[1,1,1,1,1,1,1,1,1,1]
];

#模拟走路
function step($x, $y){
    #逆时针走动
    $diretion = [
        [$x-1,$y],                                    #左
        [$x,$y+1],                                    #上
        [$x+1,$y],                                    #右
        [$x,$y-1]                                     #下
    ];
    return $directioin;
}

#逃出迷宫
/**
*@param    $x,$y,起点位置;$x1,$y1,出口位置;$moze迷宫
*@return    跳出路径
**/
function escape_moze($x,$y,$x1,$y1,$moze){
    $stack = new Stack();
    $stack->push([$x,$y]);                            #初始化起点
    while($stack->stack_is_null()){                  #走出后退出
        $top = $stack->get_top();
        if($top[0] == $x1 && $top[1] == $y1){         #走到终点
            return $stack->get_stack();
        }

        $direciton = step($top[0], $top[1]);
        $i = 0;                                       #4个方向出法
        $target = 0;                                  #是否走进死胡同

        while($i < 4) {
            $d = $dirction[$i];
            if($moze[$d[0]][[$d[1]]] == 0){           #可以走
                $stack->push($d);                     #入栈
                $moze[$d[0]][$d[1]] = 2;              #并标记走过的路
                $l = 1;
                break;
            }
            $i++;
        }
        if(!$i){                                      #走进死胡同
            $moze[$d[0]][$d[1]] = 2;                  #标记当前走过的路
            $stack->pop();                            #后退一步
        }
    }
    return null;                                      #没路
}

$res = escpe_moze(1,1,8,8,$moze);
if($res){
    echo '有路';
}else{
    echo '没有路';
}

如果上面你看不太明白,还可以进一步把走出的迷宫路径打印出来;

/**
*画出路径路
*@stack,路径步骤,@moze,迷宫
**/
function draw($stack, $moze){
    $k = 1;
    foreach($stack as $key => $value){
        $moze[$value[0]][$value[1]] = $k;            #记录路径
        $k++;                                        #每走一步加一
    }

    foreach($moze as $key => $value){
        $foreach($value as $k=> $v){
            if($v<10){
                echo $v.'$nbsp$nbsp$nbsp$nbsp$nbsp';    #不够两位需要补空格
            }
            echo $v.'&nbsp&nbsp&nbsp';
        }
    }
    echo '<br>';

}

画出结果如下

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值