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 相关文章推荐
一个简单计数器的源代码
Oct 09 PHP
PHP下几种删除目录的方法总结
Aug 19 PHP
PHP中遍历stdclass object的实现代码
Jun 09 PHP
PHP filter_var() 函数 Filter 函数
Apr 25 PHP
php堆排序(heapsort)练习
Nov 13 PHP
php之curl实现http与https请求的方法
Oct 21 PHP
php 删除cookie方法详解
Dec 01 PHP
详谈PHP编码转换问题
Jul 28 PHP
php表单提交实例讲解
Nov 12 PHP
详谈php ip2long 出现负数的原因及解决方法
Apr 05 PHP
thinkPHP中钩子的使用方法实例分析
Nov 16 PHP
php strftime函数获取日期时间(switch用法)
May 16 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 将逗号、空格、回车分隔的字符串转换为数组的函数
2012/06/07 PHP
PHP添加Xdebug扩展的方法
2014/02/12 PHP
PHP统计目录大小的自定义函数分享
2014/11/18 PHP
图片自动更新(说明)
2006/10/02 Javascript
javascript 特殊字符串
2009/02/25 Javascript
6款新颖的jQuery和CSS3进度条插件推荐
2013/03/05 Javascript
JS的get和set使用示例
2014/02/20 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
浅谈react前后端同构渲染
2017/09/20 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
2017/12/07 Javascript
vue实现微信二次分享以及自定义分享的示例
2019/03/20 Javascript
JS实现求字符串中出现最多次数的字符和次数示例
2019/07/05 Javascript
微信小程序实现左滑动删除效果
2020/03/30 Javascript
Node.js API详解之 dns模块用法实例分析
2020/05/15 Javascript
[00:52]黑暗之门更新 新英雄孽主驾临DOTA2
2016/08/24 DOTA
利用python模拟实现POST请求提交图片的方法
2017/07/25 Python
深入学习Python中的上下文管理器与else块
2017/08/27 Python
微信跳一跳自动运行python脚本
2018/01/08 Python
在CMD命令行中运行python脚本的方法
2018/05/12 Python
python实现基于信息增益的决策树归纳
2018/12/18 Python
Python中一些深不见底的“坑”
2019/06/12 Python
基于Python实现扑克牌面试题
2019/12/11 Python
python爬虫添加请求头代码实例
2019/12/28 Python
python3.4中清屏的处理方法
2020/07/06 Python
Bally巴利英国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/07 全球购物
下面关于"联合"的题目的输出是什么
2013/08/06 面试题
机电专业体育教师求职信
2013/09/21 职场文书
函授本科毕业生自我鉴定
2013/10/16 职场文书
师恩难忘教学反思
2014/04/27 职场文书
学习与创新自我评价
2015/03/09 职场文书
中国梦宣传标语口号
2015/12/26 职场文书
《搭石》教学反思
2016/02/18 职场文书
2016年小学“感恩教师”主题队日活动总结
2016/04/01 职场文书
HTML常用标签超详细整理
2022/03/19 HTML / CSS