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 ...
随机推荐
- web服务版智能语音对话
在前几篇的基础上,我们有了语音识别,语音合成,智能机器人,那么我们是不是可以创建一个可以实时对象的机器人了? 当然可以! 一,web版智能对话 前提:你得会flask和websocket 1 ,创建f ...
- PCM时序
PCM(Pulse Code Modulation),脉冲编码调制,PCM总线用于传输数字语音信号,包括4根信号线:FSYNC(同步)/PCLK(时钟)/DTX(发送)/DRX(接收) PCM分为Ma ...
- 使用Cloudera Manager部署HUE
使用Cloudera Manager部署HUE 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.添加HUE服务 1>.进入CM服务安装向导 2>.选择需要安装的h ...
- asp.net core 读取Appsettings.json 配置文件
Appsettingsjson 配置定义实体在StartUp时读取配置信息修改你的Controller通过构造函数进入配置信息总结Appsettings.json 配置很明显这个配置文件就是一个jso ...
- 程序员常用的3大Web安全漏洞防御解决方案:XSS、CSRF及SQL注入(图文详解)
https://blog.csdn.net/ChenRui_yz/article/details/86489067 随着互联网的普及,网络安全变得越来越重要,程序员需要掌握最基本的web安全防范,下面 ...
- 倍增法求lca:暗的连锁
https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...
- *.Net框架 - IGrouping类 & Lookup类
Dictionary<TKey, TValue>只为每个键支持一个值.新类Lookup<TKey, TElement>是.NET 3.5中新增的,它类似于Dictionary& ...
- Python凯撒密码和括号匹配
1.凯撒密码: 除了特殊字符不转化,其余的按照规定经行转译,以下以a~z和A~Z的字符都进行转译. plaincode = input("")print(len(plaincode ...
- 织梦关于表情符后面跟着css样式修改
织梦关于表情符后面跟着css样式修改,前段页面是会员中心里,后台是会员心情管理 前段修改路径找到member\index_do.php 大约在396行,找不到搜索 ‘对表情进行解析’ 替换下面的 ...
- luoguP3768简单的数学题
大佬们绕道吧(或跳到错误&启发后下一根横线后) 这道题吧正解是莫比乌斯反演吧,但本人有一种独创玄妙的想法去偏分 这道题是让我们求这个对吧 \((\sum_{i=1}^n\sum_{j=1}^n ...