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 相关文章推荐
支持oicq头像的留言簿(二)
Oct 09 PHP
PHP 简单日历实现代码
Oct 28 PHP
深入eAccelerator与memcached的区别详解
Jun 06 PHP
解析php中如何调用用户自定义函数
Aug 06 PHP
推荐十款免费 WordPress 插件
Mar 24 PHP
谈谈 PHP7新增功能
Dec 16 PHP
PHP汉字转换拼音的函数代码
Dec 30 PHP
thinkphp3.x中变量的获取和过滤方法详解
May 20 PHP
详解Laravel视图间共享数据与视图Composer
Aug 04 PHP
谈谈php对接芝麻信用踩的坑
Dec 01 PHP
微信公众号开发之通过接口删除菜单
Feb 20 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
Nov 19 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后台程序与Javascript的两种交互方式
2009/10/25 PHP
PH P5.2至5.5、5.6的新增功能详解
2014/07/14 PHP
php替换字符串中间字符为省略号的方法
2015/05/04 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
PHP设计模式之装饰器模式定义与用法简单示例
2018/08/13 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
用JTrackBar实现的模拟苹果风格的滚动条
2007/08/06 Javascript
HTML 自动伸缩的表格Table js实现
2009/04/01 Javascript
利用jQuery 实现GridView异步排序、分页的代码
2010/02/06 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
2014/10/17 Javascript
JS实现跟随鼠标立体翻转图片的方法
2015/05/04 Javascript
js实现的全国省市二级联动下拉选择菜单完整实例
2015/08/17 Javascript
给before和after伪元素设置js效果的方法
2015/12/04 Javascript
jQuery图片旋转插件jQueryRotate.js用法实例(附demo下载)
2016/01/21 Javascript
JavaScript中的各种操作符使用总结
2016/05/26 Javascript
vue.js项目中实用的小技巧汇总
2017/11/29 Javascript
Angular脚手架开发的实现步骤
2019/04/09 Javascript
使用express来代理服务的方法
2019/06/21 Javascript
Vue实现手机扫描二维码预览页面效果
2020/05/28 Javascript
JavaScript冒泡算法原理与实现方法深入理解
2020/06/04 Javascript
[44:41]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python输出9*9乘法表的方法
2015/05/25 Python
Python中set与frozenset方法和区别详解
2016/05/23 Python
TensorFlow Session使用的两种方法小结
2018/07/30 Python
python的concat等多种用法详解
2018/11/28 Python
Python pandas自定义函数的使用方法示例
2019/11/20 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
canvas绘制树形结构可视图形的实现
2020/04/03 HTML / CSS
Fanatics官网:运动服装、球衣、运动装备
2020/10/12 全球购物
简单英文演讲稿
2014/01/01 职场文书
《列夫托尔斯泰》教学反思
2014/02/10 职场文书
培训班主持词
2014/03/28 职场文书
青年志愿者活动总结
2014/04/26 职场文书
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android
JavaScript中MutationObServer监听DOM元素详情
2021/11/27 Javascript
为自由献出你的心脏!「进击的巨人展 FINAL」2022年6月在台开展
2022/04/13 日漫