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 相关文章推荐
Windows下PHP的任意文件执行漏洞
Oct 09 PHP
php下封装较好的数字分页方法
Nov 23 PHP
php全局变量和类配合使用深刻理解
Jun 05 PHP
实用的简单PHP分页集合包括使用方法
Oct 21 PHP
php去除字符串换行符示例分享
Feb 13 PHP
ThinkPHP调用百度翻译类实现在线翻译
Jun 26 PHP
php密码生成类实例
Sep 24 PHP
PHP简单数据库操作类实例【支持增删改查及链式操作】
Oct 10 PHP
PHP实现字符串翻转功能的方法【递归与循环算法】
Nov 03 PHP
php微信公众号开发之二级菜单
Oct 20 PHP
php设计模式之观察者模式定义与用法经典示例
Sep 19 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
Feb 21 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实现多服务器共享SESSION数据的方法
2007/03/16 PHP
php页面缓存ob系列函数介绍
2012/10/18 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
PHP中__autoload和Smarty冲突的简单解决方法
2016/04/08 PHP
php中static和const关键字用法分析
2016/12/07 PHP
如何直接访问php实例对象中的private属性详解
2017/10/12 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
2018/08/20 PHP
微信公众号之主动给用户发送消息功能
2019/06/22 PHP
PHP实现简单的计算器
2020/08/28 PHP
颜色选择器 Color Picker,IE,Firefox,Opera,Safar
2010/11/25 Javascript
30分钟就入门的正则表达式基础教程
2013/02/25 Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
2014/08/27 Javascript
Javascript实现的Map集合工具类完整实例
2015/07/31 Javascript
浅析Javascript中bind()方法的使用与实现
2016/04/29 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
详解js中==与===的区别
2017/01/08 Javascript
ES6新特性一: let和const命令详解
2017/04/20 Javascript
详解Vuex中mapState的具体用法
2017/09/28 Javascript
vue页面离开后执行函数的实例
2018/03/13 Javascript
JavaScript Date对象功能与用法学习记录
2020/04/28 Javascript
vue实现给div绑定keyup的enter事件
2020/07/31 Javascript
在Vue 中获取下拉框的文本及选项值操作
2020/08/13 Javascript
Python正则表达式教程之二:捕获篇
2017/03/02 Python
带你认识Django
2019/01/15 Python
python使用Plotly绘图工具绘制水平条形图
2020/03/25 Python
美国杂志订阅折扣与优惠网站:Magazines.com
2016/08/31 全球购物
eDreams葡萄牙:全球最大的在线旅行社之一
2019/04/15 全球购物
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
大学毕业感言100字
2014/02/03 职场文书
大学生社会实践活动总结
2014/07/03 职场文书
个人年终总结结尾
2015/03/06 职场文书
2015年汽车销售工作总结
2015/04/07 职场文书
2015年反腐倡廉工作总结
2015/05/14 职场文书
消防演习感想
2015/08/10 职场文书
防溺水主题班会教案
2015/08/12 职场文书