PHP树生成迷宫及A*自己主动寻路算法

迷宫算法是採用树的深度遍历原理。这样生成的迷宫相当的细,并且死胡同数量相对较少!

随意两点之间都存在唯一的一条通路。

至于A*寻路算法是最大众化的一全自己主动寻路算法

完整代码已上传,http://download.csdn.net/detail/hello_katty/8885779 ,此处做些简单解释,还须要大家自己思考动手。废话不多说,贴上带代码

迷宫生成类:

  1. /** 生成迷宫类
  2. * @date 2015-07-10
  3. * @edit http://www.lai18.com
  4. * @version 1
  5. **/
  6. class Maze{
  7.  
  8. // Maze Create
  9.  
  10. private $_w;
  11.  
  12. private $_h;
  13.  
  14. private $_grids;
  15.  
  16. private $_walkHistory;
  17.  
  18. private $_walkHistory2;
  19.  
  20. private $_targetSteps;
  21.  
  22. // Construct
  23.  
  24. public function Maze() {
  25.  
  26. $this->_w = 6;
  27.  
  28. $this->_h = 6;
  29.  
  30. $this->_grids = array();
  31.  
  32. }
  33.  
  34. // 设置迷宫大小
  35.  
  36. public function set($width = 6, $height = 6) {
  37.  
  38. if ( $width > 0 ) $this->_w = $width;
  39.  
  40. if ( $height > 0 ) $this->_h = $height;
  41.  
  42. return $this;
  43.  
  44. }
  45.  
  46. // 取到迷宫
  47.  
  48. public function get() {
  49.  
  50. return $this->_grids;
  51.  
  52. }
  53.  
  54. // 生成迷宫
  55.  
  56. public function create() {
  57.  
  58. $this->_init();
  59.  
  60. return $this->_walk(rand(0, count($this->_grids) -1 ));
  61.  
  62. }
  63.  
  64. // 获取死胡同点
  65.  
  66. public function block($n = 0, $rand = false) {
  67.  
  68. $l = count($this->_grids);
  69.  
  70. for( $i = 1; $i < $l; $i++ ) {
  71.  
  72. $v = $this->_grids[$i];
  73.  
  74. if ( $v == 1 || $v == 2 || $v == 4 || $v == 8 ) {
  75.  
  76. $return[] = $i;
  77.  
  78. }
  79.  
  80. }
  81.  
  82. // 随机取点
  83.  
  84. if ( $rand ) shuffle($return);
  85.  
  86. if ( $n == 0 ) return $return;
  87.  
  88. if ( $n == 1 ) {
  89.  
  90. return array_pop($return);
  91.  
  92. } else {
  93.  
  94. return array_slice($return, 0, $n);
  95.  
  96. }
  97.  
  98. }
  99.  
  100. /**
  101.  
  102. 生成迷宫的系列函数
  103.  
  104. */
  105.  
  106. private function _walk($startPos) {
  107.  
  108. $this->_walkHistory = array();
  109.  
  110. $this->_walkHistory2 = array();
  111.  
  112. $curPos = $startPos;
  113.  
  114. while ($this->_getNext0() != -1) {
  115.  
  116. $curPos = $this->_step($curPos);
  117.  
  118. if ( $curPos === false ) break;
  119.  
  120. }
  121.  
  122. return $this;
  123.  
  124. }
  125.  
  126. private function _getTargetSteps($curPos) {
  127.  
  128. $p = 0;
  129.  
  130. $a = array();
  131.  
  132. $p = $curPos - $this->_w;
  133.  
  134. if ($p > 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
  135.  
  136. array_push($a, $p);
  137.  
  138. } else {
  139.  
  140. array_push($a, -1);
  141.  
  142. }
  143.  
  144. $p = $curPos + 1;
  145.  
  146. if ($p % $this->_w != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
  147.  
  148. array_push($a, $p);
  149.  
  150. } else {
  151.  
  152. array_push($a, -1);
  153.  
  154. }
  155.  
  156. $p = $curPos + $this->_w;
  157.  
  158. if ($p < count($this->_grids) && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
  159.  
  160. array_push($a, $p);
  161.  
  162. } else {
  163.  
  164. array_push($a, -1);
  165.  
  166. }
  167.  
  168. $p = $curPos - 1;
  169.  
  170. if (($curPos % $this->_w) != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
  171.  
  172. array_push($a, $p);
  173.  
  174. } else {
  175.  
  176. array_push($a, -1);
  177.  
  178. }
  179.  
  180. return $a;
  181.  
  182. }
  183.  
  184. private function _noStep() {
  185.  
  186. $l = count($this->_targetSteps);
  187.  
  188. for ($i = 0; $i < $l; $i ++) {
  189.  
  190. if ($this->_targetSteps[$i] != -1) return false;
  191.  
  192. }
  193.  
  194. return true;
  195.  
  196. }
  197.  
  198. private function _step($curPos) {
  199.  
  200. $this->_targetSteps = $this->_getTargetSteps($curPos);
  201.  
  202. if ( $this->_noStep() ) {
  203.  
  204. if ( count($this->_walkHistory) > 0 ) {
  205.  
  206. $tmp = array_pop($this->_walkHistory);
  207.  
  208. } else {
  209.  
  210. return false;
  211.  
  212. }
  213.  
  214. array_push($this->_walkHistory2, $tmp);
  215.  
  216. return $this->_step($tmp);
  217.  
  218. }
  219.  
  220. $r = rand(0, 3);
  221.  
  222. while ( $this->_targetSteps[$r] == -1) {
  223.  
  224. $r = rand(0, 3);
  225.  
  226. }
  227.  
  228. $nextPos = $this->_targetSteps[$r];
  229.  
  230. $isCross = false;
  231.  
  232. if ( $this->_grids[$nextPos] != 0)
  233.  
  234. $isCross = true;
  235.  
  236. if ($r == 0) {
  237.  
  238. $this->_grids[$curPos] ^= 1;
  239.  
  240. $this->_grids[$nextPos] ^= 4;
  241.  
  242. } elseif ($r == 1) {
  243.  
  244. $this->_grids[$curPos] ^= 2;
  245.  
  246. $this->_grids[$nextPos] ^= 8;
  247.  
  248. } elseif ($r == 2) {
  249.  
  250. $this->_grids[$curPos] ^= 4;
  251.  
  252. $this->_grids[$nextPos] ^= 1;
  253.  
  254. } elseif ($r == 3) {
  255.  
  256. $this->_grids[$curPos] ^= 8;
  257.  
  258. $this->_grids[$nextPos] ^= 2;
  259.  
  260. }
  261.  
  262. array_push($this->_walkHistory, $curPos);
  263.  
  264. return $isCross ?
  265.  
  266. false : $nextPos;
  267.  
  268. }
  269.  
  270. private function _isRepeating($p) {
  271.  
  272. $l = count($this->_walkHistory);
  273.  
  274. for ($i = 0; $i < $l; $i ++) {
  275.  
  276. if ($this->_walkHistory[$i] == $p) return true;
  277.  
  278. }
  279.  
  280. $l = count($this->_walkHistory2);
  281.  
  282. for ($i = 0; $i < $l; $i ++) {
  283.  
  284. if ($this->_walkHistory2[$i] == $p) return true;
  285.  
  286. }
  287.  
  288. return false;
  289.  
  290. }
  291.  
  292. private function _getNext0() {
  293.  
  294. $l = count($this->_grids);
  295.  
  296. for ($i = 0; $i <= $l; $i++ ) {
  297.  
  298. if ( $this->_grids[$i] == 0) return $i;
  299.  
  300. }
  301.  
  302. return -1;
  303.  
  304. }
  305.  
  306. private function _init() {
  307.  
  308. $this->_grids = array();
  309.  
  310. for ($y = 0; $y < $this->_h; $y ++) {
  311.  
  312. for ($x = 0; $x < $this->_w; $x ++) {
  313.  
  314. array_push($this->_grids, 0);
  315.  
  316. }
  317.  
  318. }
  319.  
  320. return $this;
  321.  
  322. }
  323.  
  324. }

A*寻路算法

  1. /** 寻路算法
  2. * @date 2015-07-10
  3. * @edit http://www.lai18.com
  4. * @version 1
  5. **/
  6. class AStar{
  7.  
  8. // A-star
  9.  
  10. private $_open;
  11.  
  12. private $_closed;
  13.  
  14. private $_start;
  15.  
  16. private $_end;
  17.  
  18. private $_grids;
  19.  
  20. private $_w;
  21.  
  22. private $_h;
  23.  
  24. // Construct
  25.  
  26. public function AStar(){
  27.  
  28. $this->_w = null;
  29.  
  30. $this->_h = null;
  31.  
  32. $this->_grids = null;
  33.  
  34. }
  35.  
  36. public function set($width, $height, $grids) {
  37.  
  38. $this->_w = $width;
  39.  
  40. $this->_h = $height;
  41.  
  42. $this->_grids = $grids;
  43.  
  44. return $this;
  45.  
  46. }
  47.  
  48. // 迷宫中寻路
  49.  
  50. public function search($start = false, $end = false) {
  51.  
  52. return $this->_search($start, $end);
  53.  
  54. }
  55.  
  56. /**
  57.  
  58. 自己主动寻路 - A-star 算法
  59.  
  60. */
  61.  
  62. public function _search($start = false, $end = false) {
  63.  
  64. if ( $start !== false ) $this->_start = $start;
  65.  
  66. if ( $end !== false ) $this->_end = $end;
  67.  
  68. $_sh = $this->_getH($start);
  69.  
  70. $point['i'] = $start;
  71.  
  72. $point['f'] = $_sh;
  73.  
  74. $point['g'] = 0;
  75.  
  76. $point['h'] = $_sh;
  77.  
  78. $point['p'] = null;
  79.  
  80. $this->_open[] = $point;
  81.  
  82. $this->_closed[$start] = $point;
  83.  
  84. while ( 0 < count($this->_open) ) {
  85.  
  86. $minf = false;
  87.  
  88. foreach( $this->_open as $key => $maxNode ) {
  89.  
  90. if ( $minf === false || $minf > $maxNode['f'] ) {
  91.  
  92. $minIndex = $key;
  93.  
  94. }
  95.  
  96. }
  97.  
  98. $nowNode = $this->_open[$minIndex];
  99.  
  100. unset($this->_open[$minIndex]);
  101.  
  102. if ( $nowNode['i'] == $this->_end ) {
  103.  
  104. $tp = array();
  105.  
  106. while( $nowNode['p'] !== null ) {
  107.  
  108. array_unshift($tp, $nowNode['p']);
  109.  
  110. $nowNode = $this->_closed[$nowNode['p']];
  111.  
  112. }
  113.  
  114. array_push($tp, $this->_end);
  115.  
  116. break;
  117.  
  118. }
  119.  
  120. $this->_setPoint($nowNode['i']);
  121.  
  122. }
  123.  
  124. $this->_closed = array();
  125.  
  126. $this->_open = array();
  127.  
  128. return $tp;
  129.  
  130. }
  131.  
  132. private function _setPoint($me) {
  133.  
  134. $point = $this->_grids[$me];
  135.  
  136. // 全部可选方向入队列
  137.  
  138. if ( $point & 1 ) {
  139.  
  140. $next = $me - $this->_w;
  141.  
  142. $this->_checkPoint($me, $next);
  143.  
  144. }
  145.  
  146. if ( $point & 2 ) {
  147.  
  148. $next = $me + 1;
  149.  
  150. $this->_checkPoint($me, $next);
  151.  
  152. }
  153.  
  154. if ( $point & 4 ) {
  155.  
  156. $next = $me + $this->_w;
  157.  
  158. $this->_checkPoint($me, $next);
  159.  
  160. }
  161.  
  162. if ( $point & 8 ) {
  163.  
  164. $next = $me - 1;
  165.  
  166. $this->_checkPoint($me, $next);
  167.  
  168. }
  169.  
  170. }
  171.  
  172. private function _checkPoint($pNode, $next) {
  173.  
  174. if ( $this->_closed[$next] ) {
  175.  
  176. $_g = $this->_closed[$pNode]['g'] + $this->_getG($next);
  177.  
  178. if ( $_g < $check['g'] ) {
  179.  
  180. $this->_closed[$next]['g'] = $_g;
  181.  
  182. $this->_closed[$next]['f'] = $this->_closed[$next]['g'] + $this->_closed[$next]['h'];
  183.  
  184. $this->_closed[$next]['p'] = $pNode;
  185.  
  186. }
  187.  
  188. } else {
  189.  
  190. $point['p'] = $pNode;
  191.  
  192. $point['h'] = $this->_getH($next);
  193.  
  194. $point['g'] = $this->_getG($next);
  195.  
  196. $point['f'] = $point['h'] + $point['g'];
  197.  
  198. $point['i'] = $next;
  199.  
  200. $this->_open[] = $point;
  201.  
  202. $this->_closed[$next] = $point;
  203.  
  204. }
  205.  
  206. }
  207.  
  208. private function _getG($point) {
  209.  
  210. return abs($this->_start - $point);
  211.  
  212. }
  213.  
  214. private function _getH($point) {
  215.  
  216. return abs($this->_end - $point);
  217.  
  218. }
  219.  
  220. }

延伸阅读

1算法导论:选择排序的原理与实现

2一道PHP冒泡排序算法笔试题

3WordPress的用户password计算算法

4PHP实现四种经常使用的排序算法

5很直观的数据结构与算法演示

6深入探讨各种背包算法问题

7图解插入排序算法

8图解堆排序Heap Sort算法

9约瑟夫环(Josephus)问题的C++算法模拟

10趣味算法之兔子产子问题

11一些常见算法的JavaScript实现

12趣味算法之猴子吃桃问题

13平方根sqrt()函数的底层算法效率

14二叉搜索树的一些相关算法介绍

15欧几里德算法(辗转相处法)练手

16蚂蚁爬木杆问题的算法思路

17计算机编程中一些重要的算法

18面试中常见的一些算法问题

19JavaScript排序算法之希尔排序

20JavaScript排序算法之堆排序

21JavaScript排序算法之归并排序

22JavaScript排序算法之选择排序

23JavaScript排序算法之高速排序

24JavaScript排序算法之冒泡排序

25JavaScript排序算法之插入排序

26合并排序算法讲解与样例

27丑数Ugly Number查找算法

28求大数阶乘的算法

29各排序算法的C++实现与性能測试

30算法导论中一个蒙提霍尔问题

31实现一个栈并获取其最小元素

32亲身体验一下KMP算法

33面试算法题的高速思考方法

34矩阵逆时针旋转的算法

35Hash魔法:分布式哈希算法

36Hash魔法:一致性 hash 算法

37字符串逆序的各种实现算法

38用递归实现的高速排序

39收集一些top软件公司经典算法面试题

40趣味算法:猴子搬香蕉问题

41一些主流的个性化推荐算法评析

42趣味算法:生男生女的比例

43趣味算法:老鼠试毒瓶问题

44使用PHP内置的DES算法函数实现数据加密解密

45第九话:数据结构与算法的关系

46第12话:什么样的算法才是好算法

47第11话:算法的五个基本特征

48第13话:算法的性能分析

49第10话:什么是算法?

50第16话:算法的空间复杂度

51第15话:算法的最坏情况与平均情况

52第14话:怎样计算算法的时间复杂度

53顺序栈的进栈操作

54顺序栈:栈的顺序存储结构

55栈的定义与大概理解

56栈的抽象数据类型ADT

57链栈:栈的链式存储结构

58链栈的进栈操作

59获取顺序栈的栈顶元素

60顺序栈的出栈操作

61为什么要使用栈这样的数据结构

62链栈的置空操作与推断链栈是否为空

63递归。栈的重要应用之中的一个

64栈是怎样实现递归的

65链栈的出栈操作

66链栈的初始化与遍历

67漫谈递归:递归的思想

68漫谈递归:递归须要满足的两个条件

69漫谈递归:字符串回文现象的递归推断

70漫谈递归:二分查找算法的递归实现

71漫谈递归:递归的效率问题

72漫谈递归:递归与循环

73漫谈递归:循环与迭代是一回事吗?

74漫谈递归:从斐波那契開始了解尾递归

75漫谈递归:尾递归与CPS

76漫谈递归:补充一些Continuation的知识

77漫谈递归:PHP里的尾递归及其优化

78漫谈递归:从汇编看尾递归的优化

79高速排序里的学问:从猜数字開始

80高速排序里的学问:再看看称球问题

81高速排序里的学问:信息熵

82高速排序里的学问:高速排序的过程

83高速排序里的学问:霍尔与高速排序

84高速排序里的学问:霍尔快排的实现

85高速排序里的学问:枢纽元选择与算法效率

86高速排序里的学问:随机化快排

87Java程序猿必须掌握的8大排序算法

88RSA,DSA等加解密算法介绍

89权限项目总结(一)权限设计

延伸阅读


PHP树生成迷宫及A*自己主动寻路算法的更多相关文章

  1. BZOJ4006 JLOI2015 管道连接(斯坦纳树生成森林)

    4006: [JLOI2015]管道连接 Time Limit: 30 Sec Memory Limit: 128 MB Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的 ...

  2. 玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)

    关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?i ...

  3. canvas——随机生成迷宫

    先上图. 效果 代码 随机生成迷宫要求任意两点都能够找到相同的路径,也就是说,迷宫是一个连通图.随机生成迷宫可以使用普里姆算法.广度优先算法.深度优先算法等实现.这里将使用普里姆算法通过生成最小数的方 ...

  4. php生成迷宫和迷宫寻址算法实例

    较之前的终于有所改善.生成迷宫的算法和寻址算法其实是一样.只是一个用了遍历一个用了递归.参考了网上的Mike Gold的算法. <?php //zairwolf z@cot8.com heade ...

  5. UWP开发:自动生成迷宫&自动寻路算法(3)

    + , + ];//0<=x<=12 0<=y<=24 private static Random Rd = new Random(); 首先声明mazeMap存储数据,声明了 ...

  6. Prim算法生成迷宫

    初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...

  7. Unity_Dungeonize 随机生成迷宫

    本文对随机生成迷宫的实现思路进行记录,其作用在于为游戏过程提供随机性以及节省开发周期,下面是Dungeonize的结构 随机迷宫的生成主要包括几个阶段 1.生成房间体结构,为墙体,自定义房间,自定义物 ...

  8. .NET技术-6.0. Expression 表达式树 生成 Lambda

    .NET技术-6.0. Expression 表达式树 生成 Lambda public static event Func<Student, bool> myevent; public ...

  9. 【Javascript + Vue】实现随机生成迷宫图片

    前言 成品预览:https://codesandbox.io/s/maze-vite-15-i7oik?file=/src/maze.js 不久前写了一篇文章介绍了如何解迷宫:https://www. ...

随机推荐

  1. Unable to execute dex: Multiple dex files define 问题

    今天在run公司的android project时候,报这个错误. 1. Clean Project, 重启Eclipse 没有解决. 2. 看到别人遇到的相同错误,解决方法如下: http://bl ...

  2. 如何从fragment跳到activity再从activity返回(finish()方法返回)刷新fragemnt页面

    代码改变世界 如何从fragment跳到activity再从activity返回(finish()方法返回)刷新fragemnt页面 广播方法实现Fragment页面刷新 fragment中重写onA ...

  3. Python的高阶函数小结

    一. 高阶函数定义 简而言之,Python的高阶函数就是指一个函数作为参数传递给另外一个函数的用法. 举一个最简单的高阶函数来说明: >>> def add(x,y,f): retu ...

  4. SYZOJ 186 [额]你猜是不是DP(哈希+二分答案+二分搜索)

      题目描述 现在给两个仅包含小写字母的字符串a,b ,求a 与b的最长公共连续子串的长度. 输入格式 两个字符串 输出格式 一个整数,为输入的两个字符串的最长公共连续子串的长度 测试样例 输入 qa ...

  5. canvas图片跨域问题

    canvas的drawImage使用跨域图片时候,会报错,解决方法如下: 1. 使用base64替换跨域图片 如果图片不大,且只有几张,可以使用base64,来代替跨域引用图片. 2. 设置image ...

  6. 秀秀的森林(forest)

    秀秀的森林(forest) 题目要求树上两条不相交的链,且要求权值的和最大 性质: 1.如果某棵树上的最长链端点为x,y,则该树上任意一点z出发的最长链为max(xz,zy) 2如果两个点被连进了树里 ...

  7. webpack-dev-server 支持其他设备访问配置

    webpack-dev-server 打开的服务默认是只能localhost访问的,当有时候需要让别人访问的时候可以配置 --host 192.168.84 这样在同一个局域网下面就可以通过该ip来访 ...

  8. POJ3170 Bzoj1671 [Usaco2005 Dec]Knights of Ni 骑士

    1671: [Usaco2005 Dec]Knights of Ni 骑士 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 281  Solved: 180 ...

  9. 【HDOJ5521】Meeting(最短路)

    题意:有n个点,m个点集,每个点集中有e[i]个点,同一点集的点互相之间到达需要t[i]单位的时间,求min(max(dis(1,i),dis(i,n))),i属于[1,n] 输出最小值并増序输出所有 ...

  10. MOSFET 符號解說

    符號 上面這個是 空乏型 的 MOSFET 符號 (有做過修改), 一個是 P channel, 一個是 N channel, 空乏型本身就有通道,所以中間是沒有斷掉的直線, P 代表 + , 有外放 ...