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 ...
随机推荐
- 在iMac上建立一个git仓库
前沿:一般我们去git clone 的时候,数据直接指向了某某分支的最后一次提交.想想 我们每次提交的不同点都在哪,去 当前工程文件下找到 .git 文件夹,去下面自己看看吧 - .git - .co ...
- html()方法与append()方法
注意加#!!!!!! $("#valuess").html("<input type='text' name='name' value= " + valu ...
- SQL SERVER-Alwayson原理
流程 1.异步提交模式 主副本无须确认该副本已经完成日志固化,就可提交事务. 主副本不受辅助副本的影响 辅助副本上的DB处于SYNCHRONIZING 2.同步提交模式 主副本要确认副本已经完成日志固 ...
- docker镜像批量打包
docker镜像批量打包 批量打包镜像: # docker save $(docker images | grep -v REPOSITORY | awk 'BEGIN{OFS=":&quo ...
- ubuntu下关于profile和bashrc中环境变量的理解(转)
ubuntu下关于profile和bashrc中环境变量的理解(转) (0) 写在前面 有些名词可能需要解释一下.(也可以先不看这一节,在后面看到有疑惑再上来看相关解释) $PS1和交互式运行(r ...
- http通信示例Httpclient和HttpServer
本示例源于为朋友解决一个小问题,数据库到服务器的数据传输,由于本人能力有限,暂时将它理解为从数据库中获取数取表数据,实际上有可能是文件或者其他形式的数据,不过原理都得用流传输, 首先httpclien ...
- C++ --- 编码习惯小区别
定义一个变量,最好养成C代码的习惯 C代码: 用到的变量X,要在最开始定义:先定义,用的时候在初始化: [例如] int x; //先定义 ..... ..... ; //再初始化 C++代码: 用到 ...
- linux系统编程综合练习-实现一个小型的shell程序(一)
之前已经花了不少篇幅学习了linux系统编程的很多知识点:文件与io.进程.信号.管道,而零散的知识点,怎么能够综合的串接起来是学习的一个很重要的目的,当然最好的方式就是用所学的知识点做一个项目了,所 ...
- LGOJP3952 时间复杂度
题目链接 题目链接 题解 细心模拟题.最主要就是要细心,并且注释不要嫌多&码风要好,心态要好.思路没捋清晰之前不要动手写代码. 对于\(ERR\),用栈来存放当前的数据.然后用个\(vis\) ...
- MyBatis-Plus-Generator配置
本文仅对使用MyBatis-Plus的代码生成器配置做保存,适合使用了该插件的童鞋做参考. 内部有大量默认配置,有性趣的童鞋可以研究下源码. ps:官方文档更齐全http://mp.baomidou. ...