加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP树的深度编历生成迷宫及A*自动寻路算法实例分析

发布时间:2020-12-13 02:27:45 所属栏目:PHP教程 来源:网络整理
导读:《PHP实战:PHP树的深度编历生成迷宫及A*自动寻路算法实例分析》要点: 本文介绍了PHP实战:PHP树的深度编历生成迷宫及A*自动寻路算法实例分析,希望对您有用。如果有疑问,可以联系我们。 PHP实例 本篇章节讲解PHP树的深度编历生成迷宫及A*自动寻路算法.

《PHP实战:PHP树的深度编历生成迷宫及A*自动寻路算法实例分析》要点:
本文介绍了PHP实战:PHP树的深度编历生成迷宫及A*自动寻路算法实例分析,希望对您有用。如果有疑问,可以联系我们。

PHP实例本篇章节讲解PHP树的深度编历生成迷宫及A*自动寻路算法.分享给大家供大家参考.具体分析如下:

PHP实例有一同事推荐了三思的迷宫算法,看了感觉还不错,就转成php
三思的迷宫算法是采用树的深度遍历原理,这样生成的迷宫相当的细,而且死胡同数量相对较少!
任意两点之间都存在唯一的一条通路.

PHP实例至于A*寻路算法是最大众化的一全自动寻路算法

PHP实例废话不多说,贴上带代码

PHP实例迷宫生成类:

代码如下:
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,$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,-1);
??????? }
??????? $p = $curPos + $this->_w;
??????? if ($p < count($this->_grids) && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
??????????? array_push($a,-1);
??????? }
??????? $p = $curPos - 1;
??????? if (($curPos % $this->_w) != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {
??????????? 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;
??? }
}

PHP实例A*寻路算法

代码如下:
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);
??? }
}

PHP实例完整实例代码点击此处本站下载.

有需要大家可以直接下demo,看看效果!

PHP实例希望本文所述对大家的php程序设计有所赞助.

编程之家培训学院每天发布《PHP实战:PHP树的深度编历生成迷宫及A*自动寻路算法实例分析》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读