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. ...
随机推荐
- Python面向对象之常用的特殊方法(5)
Python面向对象里面有很多特殊方法,例如__init__(构造方法),__del__(析构方法),这些方法对于面向对象编程非常重要,下面列出一些常用的特殊方法 (1)__call__ class ...
- LFTP下载远程文件
拓展阅读: https://linux.cn/article-5460-1.html
- Mysql实战之高可用HMA
author:JevonWei 版权声明:原创作品 主节点高可用 MHA是一款开源的MySQL的高可用程序,他为MySQL主从复制架构提供了automating master failover功能.M ...
- 【bzoj2529】[Poi2011]Sticks 贪心
题目描述 给出若干木棍,每根木棍有特定的颜色和长度.问能否找到三条颜色不同的木棍构成一个三角形.(注意这里所说的三角形面积要严格大于0) 输入 第一行给出一个整数k(3<=k<=50),表 ...
- 解决ie8下页面刚出现时候的晃动问题
出现这个问题的原因的页面的高度超过一屏,这个时候需要在开始的时候给 html,body {overflow:scroll;overflow-x:hidden}; 这样就可以解决这个问题了
- utf-8与unicode
举一个例子:It's 知乎日报 你看到的unicode字符集是这样的编码表: I 0049 t 0074 ' 0027 s 0073 0020 知 77e5 乎 4e4e 日 65e5 报 62a5 ...
- Mybatis Plugin插件安装破解及使用
2018年2月更新 2018年2月份,提供一个网上比较多的一个版本V3.21版本,下载资源里面有个已整合版直接解压放入C:\Users\你的用户名\.IntelliJIdea2017.3\config ...
- C++学习(二):学会使用stringstream
1.前言 今天在CppTemplateTutorial群里,有人问了一个问题:这一堆add怎么简化掉 https://wandbox.org/permlink/vDPDwMFbBIQSSymS.代码如 ...
- 删除svn控制
1.用cmd 进去所要删除的目录 2.运行 for /r ./ %a in (./) do @if exist "%a/.svn" rd /s /q "%a/.svn& ...
- Java IO 学习(二)select/poll/epoll
如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...