오후 훑 기 를 기록 한 A 성 길 찾기 알고리즘
14490 단어 js
open close
open ( close , open , , )
open close , , 。
(8 )
//
function manhattan(point, endPoint) {
return Math.abs(point.x - endPoint.x) + Math.abs(point.y - endPoint.y);
}
/**
*
* @param {Number} row
* @param {Number} col
*/
var aStar = function (row, col) {
if (row <= 0 || col <= 0) {
console.error('error query');
return;
}
//
this._list = [];
this._row = row;
this._col = col;
for (var i = 0; i < row; i++) {
this._list[i] = [];
for (var j = 0; j < col; j++) {
this._list[i][j] = 1;
}
}
};
/**
*
*/
aStar.prototype.addObstacle = function (points) {
if (typeof points.length !== 'undefined') {
for (var i = 0; i < points.length; i++) {
var point = points[i];
this._list[point.x][point.y] = 0;
}
} else {
this._list[points.x][points.y] = 0;
}
};
/**
* (direction!==4 8 )
*/
aStar.prototype.getRoute = function (startPoint, endPoint, direction) {
if (!this._list[startPoint.x][startPoint.y] || !this._list[endPoint.x][endPoint.y]) {
console.error(' ');
return [];
}
if (startPoint.x == endPoint.x && startPoint.y == endPoint.y) {
console.error(' ');
return [];
}
this._openList = []; //
this._closeList = {}; //
// open
var head = null;
var node = this._createNode(head, startPoint, endPoint);
this._addNodeToOpenList(node);
return this._getRoute(endPoint, direction);
};
aStar.prototype._getRoute = function (endPoint, direction) {
// open
var list = this._getOpenMin();
if (list.length === 0) {
return [];
}
for (var i = 0; i < list.length; i++) {
var e = list[i];
var index = e.index;
var node = e.node;
if (node.data.H === 0/** */) {
var route = [];
while (node.head) {
route.splice(0, 0, node.point);
node = node.head;
}
route.splice(0, 0, node.point);
return route;
}
// close
this._addOpenToCloseList(index, node);
//
/**
* p closed : 。
* p open : 。
* p open : , F 。 , 。
*/
this._getNeighbor(node.point, function (point) {
if (this._list[point.x][point.y]/** */ && !this._closeList[point.x + ',' + point.y]/** close */) {
var n = this._createNode(node, point, endPoint);
this._addNodeToOpenList(n);
}
}, direction);
}
return this._getRoute(endPoint, direction);
};
/**
*
*
* @param {any} point
* @param {any} cb
* @param {bool} d 8 4 , 8 8
*
*/
aStar.prototype._getNeighbor = function (point, cb, d) {
var xMin = point.x > 0 ? (point.x - 1) : 0;
var xMax = (point.x < this._col - 1) ? (point.x + 1) : point.x;
var yMin = point.y > 0 ? (point.y - 1) : 0;
var yMax = (point.y < this._row - 1) ? (point.y + 1) : point.y;
for (var i = xMin; i <= xMax; i++) {
for (var j = yMin; j <= yMax; j++) {
if (d === 4) {
//4
if ((i !== point.x && j === point.y) || (i === point.x && j !== point.y)) {
cb.call(this, { x: i, y: j });
}
} else {
if (this._judgeAcross(point, { x: i, y: j })) {
//8
if (i !== point.x || j !== point.y) {
cb.call(this, { x: i, y: j });
}
}
}
}
}
};
/**
* 8
*/
aStar.prototype._judgeAcross = function (p1, p2) {
if (p1.x !== p2.x && p1.y !== p2.y) {
if (this._list[p1.x][p2.y] === 0 && this._list[p2.x][p1.y] === 0) {
return false;
}
}
return true;
};
/**
* open close , open
*/
aStar.prototype._addOpenToCloseList = function (index, node) {
var k = node.point.x + ',' + node.point.y;
this._closeList[k] = node;
this._openList.splice(index, 1);
};
/**
* open
*/
aStar.prototype._addNodeToOpenList = function (node) {
for (var i = this._openList.length - 1; i >= 0; i--) {
var n = this._openList[i];
if (n.point.x === node.point.x && n.point.y === node.point.y) {
if (n.data.F < node.data.F) {
return;
}
this._openList.splice(i, 1);
break;
}
}
this._openList.push(node);
};
aStar.prototype._createNode = function (head, point, endPoint) {
var addG = 1;
if (head && head.x !== point.x && head.y !== point.y) {
addG = 1.414213562373095;
}
var G = head ? head.data.G + 1 : 0;
var H = manhattan(point, endPoint);
return {
head: head,
data: {
F: G + H,
G: G,
H: H
},
point: point
};
};
aStar.prototype._getOpenMin = function () {
var min = [];
var minF = 0;
for (var i = this._openList.length - 1; i >= 0; i--) {
var element = this._openList[i];
if (!minF) {
minF = element.data.F;
}
if (element.data.F === minF) {
min.push({ index: i, node: element });
} else if (element.data.F < minF) {
minF = element.data.F;
min = [{ index: i, node: element }];
}
}
return min;
};
var a = new aStar(30, 30);
a.addObstacle({ x: 0, y: 1 });
a.addObstacle({ x: 2, y: 0 });
a.addObstacle({ x: 2, y: 1 });
a.addObstacle({ x: 2, y: 2 });
a.addObstacle({ x: 1, y: 3 });
a.addObstacle({ x: 10, y: 20 });
a.addObstacle({ x: 14, y: 13 });
a.addObstacle({ x: 14, y: 14 });
a.addObstacle({ x: 14, y: 15 });
a.addObstacle({ x: 14, y: 16 });
console.time('a');
var route = a.getRoute({ x: 0, y: 0 }, { x: 20, y: 15 });
console.timeEnd('a');
for (var i = 0; i < route.length; i++) {
var p = route[i];
a._list[p.x][p.y] = '@';
}
for (var i = 0; i < a._list.length; i++) {
console.log(a._list[i].toString());
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[2022.04.19] 자바스크립트 this - 생성자 함수와 이벤트리스너에서의 this18일에 this에 대해 공부하면서 적었던 일반적인 함수나 객체에서의 this가 아닌 오늘은 이벤트리스너와 생성자 함수 안에서의 this를 살펴보기로 했다. new 키워드를 붙여 함수를 생성자로 사용할 때 this는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.