php实现的生成迷宫与迷宫寻址算法完整实例


Posted in PHP onNovember 06, 2017

本文实例讲述了php实现的生成迷宫与迷宫寻址算法。分享给大家供大家参考,具体如下:

较之前的终于有所改善。生成迷宫的算法和寻址算法其实是一样。只是一个用了遍历一个用了递归。参考了网上的Mike Gold的算法。

<?php
header('Content-Type: text/html; charset=utf-8');
error_reporting(E_ALL);
//n宫格迷宫
define('M', 39);//宫数
define("S", 20);//迷宫格大小
$_posArr = array(array(0, -1), array(1, 0), array(0, 1), array(-1, 0));//当前点寻址的四个xy方向 上右下左
//生成迷宫
$maze = array();
$mazeUnit = array(1, 1, 1, 1);//上右下左
for($x=0; $x<=M; $x++){
  for($y=0; $y<=M; $y++){
    $maze[$x][$y] = $mazeUnit;
  }
}
$maze2 = array();//破墙后的已访问格子
$mazeOrder = array();//破墙顺序
$x = $y = 0;//初始入口
while(count($maze)>0){
  $tmpArr = array();
  foreach($_posArr as $val){
    $nx = $x + $val[0];
    $ny = $y + $val[1];
    if(isset($maze[$nx][$ny])){//未破墙过的格子
      $tmpArr[] = array($nx, $ny);
    }
  }
  if($tmpArr){//有未破墙的格子,随机出一个,破墙
    list($nx, $ny) = $tmpArr[array_rand($tmpArr)];
    $maze2[$nx][$ny] = $maze[$nx][$ny];
    if(empty($maze2[$x][$y])) $maze2[$x][$y] = $maze[$x][$y];
    $pos = array($nx - $x, $ny - $y);
    foreach($_posArr as $key=>$val){//循环四个方向,找出需要破的墙
      if($pos == $val) {
        $maze2[$x][$y][$key] = 0;//原格子破墙
        $maze2[$nx][$ny][($key+2)%4] = 0;//新格子破墙
      }
    }
    //设置新的当前格后返回继续while循环
    $x = $nx;
    $y = $ny;
    $mazeOrder[] = array($x, $y);
    unset($maze[$x][$y]);//去掉已破墙的格子
    if(empty($maze[$x])) unset($maze[$x]);
  }else{//当前xy周围不存在未破墙的格子,返回上一个格子继续破墙
    array_pop($mazeOrder);
    if($mazeOrder) list($x, $y) = $mazeOrder[count($mazeOrder) - 1];
  }
}
//留出出口
$maze = $maze2;
$maze[0][0][3] = 0;
$maze[M][M][1] = 0;
//寻址
$pathArr = findPath($maze, 0, 0, false);
printMaze($maze, $pathArr);
echo "<img src='maze.png'> <a href='javascript:;' onclick='location.reload();'>刷新</a>";
//打印迷宫和寻址结果
function printMaze($maze, $pathArr){
  $im = ImageCreate((M + 1) * S + 1, (M + 1) * S + 1);
  $bg = ImageColorAllocate($im, 236, 233, 216);
  $pathColor=ImageColorAllocate($im, 255, 0, 0);
  $exitColor=ImageColorAllocate($im, 134, 255, 0);
  $borderColor = ImageColorAllocate($im, 0, 0, 0);
  ImageRectangle($im, 0, 0, (M + 1) * S, (M + 1) * S, $borderColor);//包边
  ImageLine($im, 0, 0, 0, S, $bg);//右上边开口
  ImageLine($im, (M + 1) * S, M * S, (M + 1) * S, (M + 1) * S, $bg);//左下边开口
  foreach($maze as $x=>$xarr){//生成格子
    foreach($xarr as $y=>$unit){
      if($unit[0]) ImageLine($im, $x * S, $y * S, ($x + 1) * S, $y * S, $borderColor);//上有线
      if($unit[1]) ImageLine($im, ($x + 1) * S, $y * S, ($x + 1) * S, ($y + 1) * S, $borderColor);//右有线
      if($unit[2]) ImageLine($im, $x * S, ($y + 1) * S, ($x + 1) * S, ($y + 1) * S, $borderColor);//下有线
      if($unit[3]) ImageLine($im, $x * S, $y * S, $x * S, ($y + 1) * S, $borderColor);//左有线
      //if(in_array(array($x, $y), $pathArr)) ImageFilledEllipse($im, $x * S + S/2, $y * S + S/2, S, S, $pathColor);//寻址格
      if(in_array(array($x, $y), $pathArr)) ImageString($im, 1, $x * S + S/5, $y * S + S/5, array_search(array($x, $y), $pathArr), $pathColor);//寻址格
    }
  }
  ImagePNG($im, 'maze.png');
  ImageDestroy($im);
}
//寻址函数
function findPath($maze, $x, $y, $fromxy){
  global $_posArr;
  if($x == M && $y == M){//到达出口
    Return array(array($x, $y));
  }
  foreach($_posArr as $key=>$val){
    if($maze[$x][$y][$key]) continue;//为1则不通
    $nx = $x + $val[0];
    $ny = $y + $val[1];
    if(!isset($maze[$nx][$ny]) || $fromxy == array($nx, $ny)) continue;//边界超出或为来源点
    if($pathArr = findPath($maze, $nx, $ny, array($x, $y))) {
      array_unshift($pathArr, array($x, $y));
      Return $pathArr;//能到达出口
    }
  }
  Return false;
}
?>

运行结果如下:

php实现的生成迷宫与迷宫寻址算法完整实例

PHP 相关文章推荐
用php获取远程图片并把它保存到本地的代码
Apr 07 PHP
PHP中删除变量时unset()和null的区别分析
Jan 27 PHP
php获取远程图片的两种 CURL方式和sockets方式获取远程图片
Nov 07 PHP
VB中的RasEnumConnections函数返回632错误解决方法
Jul 29 PHP
phpmyadmin提示The mbstring extension is missing的解决方法
Dec 17 PHP
PHP实现获取文件后缀名的几种常用方法
Aug 08 PHP
两种php去除二维数组的重复项方法
Nov 04 PHP
PHP获取指定日期是星期几的实现方法
Nov 30 PHP
php中通用的excel导出方法实例
Dec 30 PHP
tp5递归 无限级分类详解
Oct 18 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
Dec 25 PHP
php正则表达式使用方法整理集合
Jan 31 PHP
使用 laravel sms 构建短信验证码发送校验功能
Nov 06 #PHP
PHP中危险的file_put_contents函数详解
Nov 04 #PHP
PHP回调函数概念与用法实例分析
Nov 03 #PHP
PHP实现字符串翻转功能的方法【递归与循环算法】
Nov 03 #PHP
PHP空值检测函数与方法汇总
Nov 19 #PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 #PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 #PHP
You might like
php无限极分类实现的两种解决方法
2013/04/28 PHP
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
php实现搜索类封装示例
2016/03/31 PHP
Laravel5.5 数据库迁移:创建表与修改表示例
2019/10/23 PHP
用js实现trim()的解决办法
2013/04/16 Javascript
js闭包实例汇总
2014/11/09 Javascript
JS动态加载当前时间的方法
2015/02/09 Javascript
基于jquery实现表格内容筛选功能实例解析
2016/05/09 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
2016/11/01 Javascript
js实现导航吸顶效果
2017/02/24 Javascript
Vue2.0实现购物车功能
2017/06/05 Javascript
JavaScript实现瀑布流图片效果
2017/06/30 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
Node.js学习之内置模块fs用法示例
2020/01/22 Javascript
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
numpy中矩阵合并的实例
2018/06/15 Python
解决python 读取 log日志的编码问题
2019/12/24 Python
基于python实现地址和经纬度转换
2020/05/19 Python
如何基于python实现年会抽奖工具
2020/10/20 Python
python中watchdog文件监控与检测上传功能
2020/10/30 Python
python list的index()和find()的实现
2020/11/16 Python
使用CSS3的rem属性制作响应式页面布局的要点解析
2016/05/24 HTML / CSS
以特惠价提供在线奢侈品购物:FRMODA.com
2018/01/25 全球购物
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
英国奢侈皮具品牌:Aspinal of London
2018/09/02 全球购物
LINUX下线程,GDI类的解释
2016/12/14 面试题
自主实习接收函
2014/01/13 职场文书
工作表现自我评价
2014/02/08 职场文书
企业安全生产标语
2014/06/06 职场文书
质量主管工作职责
2014/09/26 职场文书
2014年综合治理工作总结
2014/11/20 职场文书
简历中的自我评价怎么写呢?
2019/04/30 职场文书
会计专业自荐信范文
2019/05/22 职场文书
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL
Python Django项目和应用的创建详解
2021/11/27 Python