PHP树生成迷宫及A*自己主动寻路算法
PHP树生成迷宫及A*自己主动寻路算法
随意两点之间都存在唯一的一条通路。
至于A*寻路算法是最大众化的一全自己主动寻路算法
完整代码已上传,http://download.csdn.net/detail/hello_katty/8885779 ,此处做些简单解释,还须要大家自己思考动手。废话不多说,贴上带代码
- /** 生成迷宫类
- * @date 2015-07-10
- * @edit http://www.lai18.com
- * @version 1
- **/
- class Maze{
- // Maze Create
- private $_w;
- private $_h;
- private $_grids;
- private $_walkHistory;
- private $_walkHistory2;
- private $_targetSteps;
- // Construct
- public function Maze() {
- $this->_w = 6;
- $this->_h = 6;
- $this->_grids = array();
- }
- // 设置迷宫大小
- public function set($width = 6, $height = 6) {
- if ( $width > 0 ) $this->_w = $width;
- if ( $height > 0 ) $this->_h = $height;
- return $this;
- }
- // 取到迷宫
- public function get() {
- return $this->_grids;
- }
- // 生成迷宫
- public function create() {
- $this->_init();
- return $this->_walk(rand(0, count($this->_grids) -1 ));
- }
- // 获取死胡同点
- public function block($n = 0, $rand = false) {
- $l = count($this->_grids);
- for( $i = 1; $i < $l; $i++ ) {
- $v = $this->_grids[$i];
- if ( $v == 1 || $v == 2 || $v == 4 || $v == 8 ) {
- $return[] = $i;
- }
- }
- // 随机取点
- if ( $rand ) shuffle($return);
- if ( $n == 0 ) return $return;
- if ( $n == 1 ) {
- return array_pop($return);
- } else {
- return array_slice($return, 0, $n);
- }
- }
- /**
- 生成迷宫的系列函数
- */
- private function _walk($startPos) {
- $this->_walkHistory = array();
- $this->_walkHistory2 = array();
- $curPos = $startPos;
- while ($this->_getNext0() != -1) {
- $curPos = $this->_step($curPos);
- if ( $curPos === false ) break;
- }
- return $this;
- }
- private function _getTargetSteps($curPos) {
- $p = 0;
- $a = array();
- $p = $curPos - $this->_w;
- if ($p > 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
- array_push($a, $p);
- } else {
- array_push($a, -1);
- }
- $p = $curPos + 1;
- if ($p % $this->_w != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
- array_push($a, $p);
- } else {
- array_push($a, -1);
- }
- $p = $curPos + $this->_w;
- if ($p < count($this->_grids) && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
- array_push($a, $p);
- } else {
- array_push($a, -1);
- }
- $p = $curPos - 1;
- if (($curPos % $this->_w) != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
- array_push($a, $p);
- } else {
- array_push($a, -1);
- }
- return $a;
- }
- private function _noStep() {
- $l = count($this->_targetSteps);
- for ($i = 0; $i < $l; $i ++) {
- if ($this->_targetSteps[$i] != -1) return false;
- }
- return true;
- }
- private function _step($curPos) {
- $this->_targetSteps = $this->_getTargetSteps($curPos);
- if ( $this->_noStep() ) {
- if ( count($this->_walkHistory) > 0 ) {
- $tmp = array_pop($this->_walkHistory);
- } else {
- return false;
- }
- array_push($this->_walkHistory2, $tmp);
- return $this->_step($tmp);
- }
- $r = rand(0, 3);
- while ( $this->_targetSteps[$r] == -1) {
- $r = rand(0, 3);
- }
- $nextPos = $this->_targetSteps[$r];
- $isCross = false;
- if ( $this->_grids[$nextPos] != 0)
- $isCross = true;
- if ($r == 0) {
- $this->_grids[$curPos] ^= 1;
- $this->_grids[$nextPos] ^= 4;
- } elseif ($r == 1) {
- $this->_grids[$curPos] ^= 2;
- $this->_grids[$nextPos] ^= 8;
- } elseif ($r == 2) {
- $this->_grids[$curPos] ^= 4;
- $this->_grids[$nextPos] ^= 1;
- } elseif ($r == 3) {
- $this->_grids[$curPos] ^= 8;
- $this->_grids[$nextPos] ^= 2;
- }
- array_push($this->_walkHistory, $curPos);
- return $isCross ?
- false : $nextPos;
- }
- private function _isRepeating($p) {
- $l = count($this->_walkHistory);
- for ($i = 0; $i < $l; $i ++) {
- if ($this->_walkHistory[$i] == $p) return true;
- }
- $l = count($this->_walkHistory2);
- for ($i = 0; $i < $l; $i ++) {
- if ($this->_walkHistory2[$i] == $p) return true;
- }
- return false;
- }
- private function _getNext0() {
- $l = count($this->_grids);
- for ($i = 0; $i <= $l; $i++ ) {
- if ( $this->_grids[$i] == 0) return $i;
- }
- return -1;
- }
- private function _init() {
- $this->_grids = array();
- for ($y = 0; $y < $this->_h; $y ++) {
- for ($x = 0; $x < $this->_w; $x ++) {
- array_push($this->_grids, 0);
- }
- }
- return $this;
- }
- }
A*寻路算法
- /** 寻路算法
- * @date 2015-07-10
- * @edit http://www.lai18.com
- * @version 1
- **/
- class AStar{
- // A-star
- private $_open;
- private $_closed;
- private $_start;
- private $_end;
- private $_grids;
- private $_w;
- private $_h;
- // Construct
- public function AStar(){
- $this->_w = null;
- $this->_h = null;
- $this->_grids = null;
- }
- public function set($width, $height, $grids) {
- $this->_w = $width;
- $this->_h = $height;
- $this->_grids = $grids;
- return $this;
- }
- // 迷宫中寻路
- public function search($start = false, $end = false) {
- return $this->_search($start, $end);
- }
- /**
- 自己主动寻路 - A-star 算法
- */
- public function _search($start = false, $end = false) {
- if ( $start !== false ) $this->_start = $start;
- if ( $end !== false ) $this->_end = $end;
- $_sh = $this->_getH($start);
- $point['i'] = $start;
- $point['f'] = $_sh;
- $point['g'] = 0;
- $point['h'] = $_sh;
- $point['p'] = null;
- $this->_open[] = $point;
- $this->_closed[$start] = $point;
- while ( 0 < count($this->_open) ) {
- $minf = false;
- foreach( $this->_open as $key => $maxNode ) {
- if ( $minf === false || $minf > $maxNode['f'] ) {
- $minIndex = $key;
- }
- }
- $nowNode = $this->_open[$minIndex];
- unset($this->_open[$minIndex]);
- if ( $nowNode['i'] == $this->_end ) {
- $tp = array();
- while( $nowNode['p'] !== null ) {
- array_unshift($tp, $nowNode['p']);
- $nowNode = $this->_closed[$nowNode['p']];
- }
- array_push($tp, $this->_end);
- break;
- }
- $this->_setPoint($nowNode['i']);
- }
- $this->_closed = array();
- $this->_open = array();
- return $tp;
- }
- private function _setPoint($me) {
- $point = $this->_grids[$me];
- // 全部可选方向入队列
- if ( $point & 1 ) {
- $next = $me - $this->_w;
- $this->_checkPoint($me, $next);
- }
- if ( $point & 2 ) {
- $next = $me + 1;
- $this->_checkPoint($me, $next);
- }
- if ( $point & 4 ) {
- $next = $me + $this->_w;
- $this->_checkPoint($me, $next);
- }
- if ( $point & 8 ) {
- $next = $me - 1;
- $this->_checkPoint($me, $next);
- }
- }
- private function _checkPoint($pNode, $next) {
- if ( $this->_closed[$next] ) {
- $_g = $this->_closed[$pNode]['g'] + $this->_getG($next);
- if ( $_g < $check['g'] ) {
- $this->_closed[$next]['g'] = $_g;
- $this->_closed[$next]['f'] = $this->_closed[$next]['g'] + $this->_closed[$next]['h'];
- $this->_closed[$next]['p'] = $pNode;
- }
- } else {
- $point['p'] = $pNode;
- $point['h'] = $this->_getH($next);
- $point['g'] = $this->_getG($next);
- $point['f'] = $point['h'] + $point['g'];
- $point['i'] = $next;
- $this->_open[] = $point;
- $this->_closed[$next] = $point;
- }
- }
- private function _getG($point) {
- return abs($this->_start - $point);
- }
- private function _getH($point) {
- return abs($this->_end - $point);
- }
- }
延伸阅读
28求大数阶乘的算法
53顺序栈的进栈操作
58链栈的进栈操作
60顺序栈的出栈操作
65链栈的出栈操作
延伸阅读
PHP树生成迷宫及A*自己主动寻路算法的更多相关文章
- BZOJ4006 JLOI2015 管道连接(斯坦纳树生成森林)
4006: [JLOI2015]管道连接 Time Limit: 30 Sec Memory Limit: 128 MB Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的 ...
- 玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)
关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?i ...
- canvas——随机生成迷宫
先上图. 效果 代码 随机生成迷宫要求任意两点都能够找到相同的路径,也就是说,迷宫是一个连通图.随机生成迷宫可以使用普里姆算法.广度优先算法.深度优先算法等实现.这里将使用普里姆算法通过生成最小数的方 ...
- php生成迷宫和迷宫寻址算法实例
较之前的终于有所改善.生成迷宫的算法和寻址算法其实是一样.只是一个用了遍历一个用了递归.参考了网上的Mike Gold的算法. <?php //zairwolf z@cot8.com heade ...
- UWP开发:自动生成迷宫&自动寻路算法(3)
+ , + ];//0<=x<=12 0<=y<=24 private static Random Rd = new Random(); 首先声明mazeMap存储数据,声明了 ...
- Prim算法生成迷宫
初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...
- Unity_Dungeonize 随机生成迷宫
本文对随机生成迷宫的实现思路进行记录,其作用在于为游戏过程提供随机性以及节省开发周期,下面是Dungeonize的结构 随机迷宫的生成主要包括几个阶段 1.生成房间体结构,为墙体,自定义房间,自定义物 ...
- .NET技术-6.0. Expression 表达式树 生成 Lambda
.NET技术-6.0. Expression 表达式树 生成 Lambda public static event Func<Student, bool> myevent; public ...
- 【Javascript + Vue】实现随机生成迷宫图片
前言 成品预览:https://codesandbox.io/s/maze-vite-15-i7oik?file=/src/maze.js 不久前写了一篇文章介绍了如何解迷宫:https://www. ...
随机推荐
- Unable to execute dex: Multiple dex files define 问题
今天在run公司的android project时候,报这个错误. 1. Clean Project, 重启Eclipse 没有解决. 2. 看到别人遇到的相同错误,解决方法如下: http://bl ...
- 如何从fragment跳到activity再从activity返回(finish()方法返回)刷新fragemnt页面
代码改变世界 如何从fragment跳到activity再从activity返回(finish()方法返回)刷新fragemnt页面 广播方法实现Fragment页面刷新 fragment中重写onA ...
- Python的高阶函数小结
一. 高阶函数定义 简而言之,Python的高阶函数就是指一个函数作为参数传递给另外一个函数的用法. 举一个最简单的高阶函数来说明: >>> def add(x,y,f): retu ...
- SYZOJ 186 [额]你猜是不是DP(哈希+二分答案+二分搜索)
题目描述 现在给两个仅包含小写字母的字符串a,b ,求a 与b的最长公共连续子串的长度. 输入格式 两个字符串 输出格式 一个整数,为输入的两个字符串的最长公共连续子串的长度 测试样例 输入 qa ...
- canvas图片跨域问题
canvas的drawImage使用跨域图片时候,会报错,解决方法如下: 1. 使用base64替换跨域图片 如果图片不大,且只有几张,可以使用base64,来代替跨域引用图片. 2. 设置image ...
- 秀秀的森林(forest)
秀秀的森林(forest) 题目要求树上两条不相交的链,且要求权值的和最大 性质: 1.如果某棵树上的最长链端点为x,y,则该树上任意一点z出发的最长链为max(xz,zy) 2如果两个点被连进了树里 ...
- webpack-dev-server 支持其他设备访问配置
webpack-dev-server 打开的服务默认是只能localhost访问的,当有时候需要让别人访问的时候可以配置 --host 192.168.84 这样在同一个局域网下面就可以通过该ip来访 ...
- POJ3170 Bzoj1671 [Usaco2005 Dec]Knights of Ni 骑士
1671: [Usaco2005 Dec]Knights of Ni 骑士 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 281 Solved: 180 ...
- 【HDOJ5521】Meeting(最短路)
题意:有n个点,m个点集,每个点集中有e[i]个点,同一点集的点互相之间到达需要t[i]单位的时间,求min(max(dis(1,i),dis(i,n))),i属于[1,n] 输出最小值并増序输出所有 ...
- MOSFET 符號解說
符號 上面這個是 空乏型 的 MOSFET 符號 (有做過修改), 一個是 P channel, 一個是 N channel, 空乏型本身就有通道,所以中間是沒有斷掉的直線, P 代表 + , 有外放 ...