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 静态变量与自定义常量的使用方法
Jan 26 PHP
PHP数组 为文章加关键字连接 文章内容自动加链接
Dec 29 PHP
php抽奖小程序的实现代码
Jun 18 PHP
解析mysql 表中的碎片产生原因以及清理
Jun 22 PHP
PHP 输出URL的快捷方式示例代码
Sep 22 PHP
php的memcache类分享(memcache队列)
Mar 26 PHP
php调用google接口生成二维码示例
Apr 28 PHP
PHP不用递归遍历目录下所有文件的代码
Jul 04 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
Oct 14 PHP
smarty的section嵌套循环用法示例
May 28 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
Feb 04 PHP
PHP 范围解析操作符(::)用法分析【访问静态成员和类常量】
Apr 14 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无限极分类递归排序实现方法
2014/11/11 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
jquery 圆形旋转图片滚动切换效果
2011/01/19 Javascript
JQuery的Ajax跨域请求原理概述及实例
2013/04/26 Javascript
从数据结构的角度分析 for each in 比 for in 快的多
2013/07/07 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
Js实现无刷新删除内容
2015/04/29 Javascript
7个jQuery最佳实践
2016/01/12 Javascript
jQuery获取浏览器类型和版本号的方法
2016/07/05 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
详解Js模板引擎(TrimPath)
2016/11/22 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
ES6扩展运算符的用途实例详解
2017/08/20 Javascript
微信小程序中this.data与this.setData的区别详解
2018/09/17 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
彻底弄懂 JavaScript 执行机制
2018/10/23 Javascript
vue 表单之通过v-model绑定单选按钮radio
2019/05/13 Javascript
TypeScript魔法堂之枚举的超实用手册
2020/10/29 Javascript
[01:00:25]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS Liquid
2018/03/31 DOTA
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
python字符串过滤性能比较5种方法
2017/06/22 Python
python之django母板页面的使用
2018/07/03 Python
python实现周期方波信号频谱图
2018/07/21 Python
win7 x64系统中安装Scrapy的方法
2018/11/18 Python
Django和Flask框架优缺点对比
2019/10/24 Python
使用CSS实现弹性视频html5案例实践
2012/12/26 HTML / CSS
Html5嵌入钉钉的实现示例
2020/06/04 HTML / CSS
喜诗官方在线巧克力店:See’s Candies
2017/01/01 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
大课间体育活动方案
2014/03/12 职场文书
导游词之贵州百里杜鹃
2019/10/29 职场文书