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 ...
随机推荐
- centos7 安装 git服务器
服务器端配置 yum install -y git groupadd git useradd git -g git 2.创建authorized_keys cd /home/git mkdir .ss ...
- layui.table前端+后台处理+分页
前端 注:监听工具条没有详细写,但路子一样的 @section head{ <script src="~/Content/jquery-easyui-1.5.5.4/jquery.ea ...
- javascript_17-基本类型和引用类型
基本类型 直接存储值 Number . String .Boolean undefined.null 引用类型 存储引用 -Object.Array.Date.函数 包装基本类型--引用类型 func ...
- Python_列表操作2
1.使用sort()方法对列表进行永久性排序: colorsList=['hong','cheng','huang','lv'] colorsList.sort() #正序排序 print(color ...
- Linux学习笔记之一
基本命令 关机/重启 [root@allen ~]# [当前登录用户@主机名 当前所在目录]# 当前用户身份 #号表示管理员root $表示普通用户登录 如何关机 如何重启 系统硬件信息查看 关机命令 ...
- 解决 SSH Connection closed by foreign host 问题
Xshell 报错 : 1.有可能是IP和别人冲突,改一下IP就好了 2.也有可能是文件权限的问题.改一下: cd /etc/ssh/ chmod ssh_host_* chmod *.pub 3.也 ...
- idea 模板
/** * @author sharplee * @version 1.0.0 * @ClassName ${PACKAGE_NAME}.${NAME} * @Description * @creat ...
- SQL EXPLAIN优化详解
使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是 如何处理你的SQL语句的.分析你的查询语句或是表结构的性能瓶颈.使用方式:Explain+SQL语句执行计划包含的信息: ...
- 创建型模式(五) 原型模式(Prototype)
一.动机(Motivation) 在软件系统中,经常面临着"某些结构复杂的对象"的创建工作:由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口.如何应对 ...
- Iconfont——实现字体图标的反转
前言 有时候找不到刚好合适的字体图标,只好找个差不多的然后再通过css再进行调整. 调整 水平反转 .icon-shexiangji1 { color: #f64e78; font-size: 20p ...