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 mssql 日期出现中文字符的解决方法
Mar 10 PHP
PHP5中新增stdClass 内部保留类
Jun 13 PHP
php中将数组存到文件里的实现代码
Jan 19 PHP
PHP抓屏函数实现屏幕快照代码分享
Jan 02 PHP
php解决约瑟夫环示例
Apr 09 PHP
PHP提高编程效率的20个要点
Sep 23 PHP
PHP+JQUERY操作JSON实例
Mar 23 PHP
PHP数组去重的更快实现方式分析
May 09 PHP
php闭包中使用use声明变量的作用域实例分析
Aug 09 PHP
laravel实现查询最后执行的一条sql语句的方法
Oct 09 PHP
在Laravel中实现使用AJAX动态刷新部分页面
Oct 15 PHP
分享几种好用的PHP自定义加密函数(可逆/不可逆)
Sep 15 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实现文件上传与下载实例与总结
2016/03/13 PHP
PHP实现数据库的增删查改功能及完整代码
2018/04/18 PHP
jQuery的实现原理的模拟代码 -3 事件处理
2010/08/03 Javascript
jQuery 一个图片切换的插件
2011/10/09 Javascript
JS控制一个DIV层在指定时间内消失的方法
2014/02/17 Javascript
深入理解JavaScript系列(49):Function模式(上篇)
2015/03/04 Javascript
浅谈Sizzle的“编译原理”
2015/04/14 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
Angular-Ui-Router+ocLazyLoad动态加载脚本示例
2017/03/02 Javascript
vue父组件中获取子组件中的数据(实例讲解)
2017/09/27 Javascript
Bootstrap3.3.7导航栏下拉菜单鼠标滑过展开效果
2017/10/31 Javascript
简单了解node npm cnpm的具体使用方法
2019/02/27 Javascript
[01:46]新英雄登场
2019/09/10 DOTA
python实现保存网页到本地示例
2014/03/16 Python
python文件操作整理汇总
2014/10/21 Python
Ubuntu 16.04 LTS中源码安装Python 3.6.0的方法教程
2016/12/27 Python
Pycharm学习教程(7)虚拟机VM的配置教程
2017/05/04 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
Python编程flask使用页面模版的方法
2018/12/28 Python
python集成开发环境配置(pycharm)
2020/02/14 Python
html5中valid、invalid、required的定义
2014/02/21 HTML / CSS
Book Depository亚太地区:一家领先的国际图书零售商
2019/05/05 全球购物
十佳班主任事迹材料
2014/01/18 职场文书
行政专员求职信范文
2014/05/03 职场文书
活动总结报告格式
2014/05/09 职场文书
义和团口号
2014/06/17 职场文书
2014年助理工程师工作总结
2014/11/14 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
致青春观后感
2015/06/09 职场文书
鲁滨孙漂流记读书笔记
2015/06/30 职场文书
公司车队管理制度
2015/08/04 职场文书
演讲稿:​快乐,从不抱怨开始!
2019/04/02 职场文书
pytorch中的model=model.to(device)使用说明
2021/05/24 Python
解决mysql的int型主键自增问题
2021/07/15 MySQL