Perl深度优先迷宫算法
迷宫求解,可以用穷举法,将每个点的方向都穷举完;由于在求解过程中会遇到某一方向不可通过,此时就必须按原路返回。
想到用Perl数组来保存路径,记录每次所探索的方向,方便原路返回时得到上一步的方向,再退回到可以通过的方向,继续探索,直到终点或者最终无法到达,正常退出程序为止。
求解过程的关键思想:
1、由于需要标记下一位置是否已探索,需要一个数组用来记录每个点是否可通过;
定义如:0--未经过 1--已走 2--不可通过
2、原路返回需要知道回退到哪个点,那么每一步要记录当前坐标;
3、采用深度优先搜索路径,每一步需记录搜索方向;
采用HASH表:{ coordinate=>[y,x] , direct=>'UP' }
4、用数组保存每一步,数组下标即代表当前步
关键算法:
北上,撞墙后原路返回,取出数组末元素,判断方向是否已搜索;已搜索完毕,继续原路返回;未搜索完,进行下个方向搜索,当前点放到数组尾。
循环。
5、算法伪码:
do{
if(当前点未经过){
设置已走
将当前位置的坐标、方向保存
if(当前点为终点){
修改迷宫的数据,记录所走的路线
return
}
当前步增一
新的坐标点=当前坐标+移动方向
}
else{ # 当前位置走不通
if(数组非空){
取出当前步
while(当前位置所走方向已搜索 && 数组非空){
记录当前位置不可通过
取出上一步状态
原路返回
}
if(当前的位置搜索方向小于4){
当前位置的方向增一
数组重新记录当前步数
新的坐标点=当前坐标+移动方向
}
}
}
}while(数组非空)
初始化迷宫:

初始化标记数组: 2、不可通过 0、未经过

路径:从蛇头到蛇尾

代码如下:
use strict;
use constant {WIDTH=>,HEIGHT=>,DEBUG=>,};
my %uldr=(=>[-,],
=>[,-],
=>[,],
=>[,],); # 上、左、下、右
my @bg=();
for(my $y=;$y<HEIGHT;$y++){
for( my $x= ; $x<WIDTH ; $x++ ){
if( $y == || $y == HEIGHT- ||
$x == || $x == WIDTH- ){
$bg[$y][$x] = '*';
}
else{
$bg[$y][$x] = ' ';
}
}
} # 初始化迷宫 my @tmp=( [,],[,],[,],[,],[,],[,],[,], ); # 障碍物坐标
map{ $bg[ $tmp[$_][] ][ $tmp[$_][] ] = '#' } ..$#tmp-1;
$bg[ $tmp[][] ][ $tmp[][] ] = '@';
print @$_,"\n" foreach(@bg); my @bg_ghost=map{ [ split('','0'x (WIDTH)) ] }..(HEIGHT-); # 0--未经过 1--已走 2--不可通过
map{ my $y=$_;map { $bg_ghost[$y][$_] = ( $bg[$y][$_] eq '#' || $bg[$y][$_] eq '*')?: }..$#{$bg[0]} }0..$#bg; # 障碍物设置不可通过 print @$_,"\n" foreach(@bg_ghost);
print "-"x15,"\n"; sub handle{
my @path=(); # 存放步数的数组
my $cur_position=[ $tmp[][] , $tmp[][] ]; # 起点
my $end=[ $tmp[-][] , $tmp[-][] ]; # 终点
my ($step,$p_step)=(,''); # 步数、指向数组元素的指针
do{
if($bg_ghost[ $cur_position->[] ][ $cur_position->[] ] == ){ # 当前位置未经过
$bg_ghost[ $cur_position->[] ][ $cur_position->[] ]=; # 设置当前位置已走
$path[$step]={step=>$step,
coordinate=>[$cur_position->[],$cur_position->[]],
direct=>,
}; # 保存当前位置信息:坐标、方向
print "path[$step]:$path[$step]:",$path[$step]->{step},"\n" if DEBUG;
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
if( $cur_position->[]==$end->[] && $cur_position->[]==$end->[]){
my @arr=('A'..'Z','a'..'z');
foreach(..$#path){
$bg[ $path[$_]->{coordinate}->[] ][ $path[$_]->{coordinate}->[] ] = $arr[$_];
}
return ;
}
$step++;
$cur_position=[ $path[$step-]->{coordinate}->[]+$uldr{}->[],
$path[$step-]->{coordinate}->[]+$uldr{}->[] ];
}
else{ # 当前位置已走/不可通过
if(@path){
$p_step=pop(@path); # 取出当前步
while($p_step->{direct}== && (@path)){ # 4个方向已经搜索完
$bg_ghost[ $p_step->{coordinate}->[] ][ $p_step->{coordinate}->[] ] = ; # 设置不可通过
$p_step=pop(@path); # 上一步状态
$step--; # 上一步编号
}
if($p_step->{direct}<){
$p_step->{direct}++;
print " step:",scalar(@path)," p_step->{direct}:",$p_step->{direct},"\n" if DEBUG;
push @path,$p_step;
my @temp=@{$p_step->{coordinate}}[,];
$cur_position = [ $temp[]+$uldr{$p_step->{direct}}->[],
$temp[]+$uldr{$p_step->{direct}}->[] ];
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
}
}
}
}while(@path);
return ;
}
my $x=&handle;
print @$_,"\n" foreach(@bg);
运行信息如下:
path[]:HASH(0x1585174):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x15849f4):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x1584a14):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x1584954):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x1584924):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x1584884):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x158479c):
(y,x):(,)
step: p_step->{direct}:
(y,x):(,)
path[]:HASH(0x158471c):
(y,x):(,)
path[]:HASH(0x158463c):
(y,x):(,)
Perl深度优先迷宫算法的更多相关文章
- perl面向对象
来源: http://www.cnblogs.com/itech/archive/2012/08/21/2649580.html Perl面向对象 首先让我们来看看有关 Perl 面向对象编程 ...
- Perl面向对象(2):对象
本系列: Perl面向对象(1):从代码复用开始 Perl面向对象(2):对象 Perl面向对象(3):解构--对象销毁 第3篇依赖于第2篇,第2篇依赖于1篇. 已有的代码结构 现在有父类Animal ...
- Perl 正则表达式语法
1. 概要 Perl正则表达式是Boost.regex 默认行为,也可以将perl传入basic_regex 构造. boost::regex e1(my_expression); boost::r ...
- Perl OOP
1. 模块/类(包) 创建一个名为Apple.pm的包文件(扩展名pm是包的缺省扩展名.意为Perl Module). 一个模块就是一个类(包). 2. new方法 new()方法是创建对象时必须被调 ...
- Perl看完这个,再不敢说自己会玩贪吃蛇
某天闲逛时看见一副动图: 真的是非常贪吃,各种拐弯各种吃,感觉十分有趣. 用Perl来实现自动吃满,蓄谋已久,之前的字符贪吃蛇.深度优先算法.A*算法,都是为此篇做铺垫. 那么,怎样让蛇不吃到自己呢? ...
- Perl寻路A*算法实现
A*算法:A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法.估价值与实际值越接近,估价函数取得就越好. 公式表示为: f(n)=g(n)+h(n),其中 f(n) 是从初始点经 ...
- Perl 的继承
Perl 类的定义 Perl的一个packag可以作为一个类使用,文件后缀名为.pm,并且把package里的函数当作类的方法来用.如: package Person; 创建和使用对象 大多数程序使用 ...
- 邻接矩阵的深度优先遍历(java版)
这是一个有向边带权的图 顶点数组:[v0, v1, v2, v3, v4] 边数组: v0 v1 v2 v3 v4 v0 6 v1 9 3 v2 2 5 v3 1 v4 package com.dat ...
- 精通Perl(第2版)
精通Perl(第2版)(通往Perl大师之路必读经典书籍,体现了一种编程思维,能够帮你解决很多实际的问题) [美]brian d foy(布瑞恩·D·福瓦)著 王兴宇 刘宸宇 译 ISBN 978 ...
随机推荐
- kubeadm添加新master或node
一.首先在master上生成新的token kubeadm token create --print-join-command [root@cn-hongkong nfs]# kubeadm toke ...
- docker及lvs负载
1.分别使用lxc容器和docker容器搭建nginx服务,能够正常访问到容器内的web服务 下载docker-ceyum仓库至 /etc/yum.repos.d/目录中,使用yum安装docker- ...
- SOAP知识点
SOAP简介: SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换. 或者更简单地说:SOAP 是用于访问网络服务的协议. 1.什么是 SOAP? SOAP 指简易对象访 ...
- 2.遍历XML即添加修改节点
1.xml <?xml version="1.0" encoding="utf-8" ?> <stories> <story ac ...
- P2261 [CQOI2007]余数求和[整除分块]
题目大意 给出正整数 n 和 k 计算 \(G(n, k)=k\ \bmod\ 1 + k\ \bmod\ 2 + k\ \bmod\ 3 + \cdots + k\ \bmod\ n\) 的值 其中 ...
- 大数据之路week07--day06 (Sqoop 的安装及配置)
Sqoop 的安装配置比较简单. 提供安装需要的安装包和连接mysql的驱动的百度云链接: 链接:https://pan.baidu.com/s/1pdFj0u2lZVFasgoSyhz-yQ 提取码 ...
- mac pro下安装brew软件包管理工具
Homebrew简称brew,OSX上的软件包管理工具,在Mac终端可以通过brew安装.更新.卸载软件. 1.打开终端直接输入下面指令回车: ruby -e "$(curl -fsSL h ...
- 移动端跨平台应用开发(ios、Android、web)- Flutter 技术
关键词:Google 出品:Dart语言:Flutter Engine引擎:响应式设计模式:原生渲染:免费并且开源 一.简介 Flutter 是谷歌2018年发布的跨平台移动UI框架.作为谷歌的开源移 ...
- 黄杉杉 --java第八次作业
题目:编写一个应用程序,创建一个矩形类,类中具有长.宽两个成员变量和求周长的方法.再创建一个矩形类的子类——正方形类,类中定义求面积方法.重写求周长的方法.在主类中,输入一个正方形边长,创建正方形对象 ...
- docker 进程 转载:
今天我们会分析Docker中进程管理的一些细节,并介绍一些常见问题的解决方法和注意事项. 容器的PID namespace(名空间) 在Docker中,进程管理的基础就是Linux内核中的PID名空间 ...