小孩子经常玩过的一种游戏——走迷宫,我们也可以用算法来解决;
下面的方案只是针对迷宫找出一种走出迷宫的方案,并不是最优路径;
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.'   ';
}
}
echo '<br>';
}
画出结果如下