lychees's picture
Upload 569 files
87b3b3a
/**
* @class Simplified A* algorithm: all edges have a value of 1
* @augments ROT.Path
* @see ROT.Path
*/
ROT.Path.AStar = function(toX, toY, passableCallback, options) {
ROT.Path.call(this, toX, toY, passableCallback, options);
this._todo = [];
this._done = {};
this._fromX = null;
this._fromY = null;
}
ROT.Path.AStar.extend(ROT.Path);
/**
* Compute a path from a given point
* @see ROT.Path#compute
*/
ROT.Path.AStar.prototype.compute = function(fromX, fromY, callback) {
this._todo = [];
this._done = {};
this._fromX = fromX;
this._fromY = fromY;
this._add(this._toX, this._toY, null);
while (this._todo.length) {
var item = this._todo.shift();
if (item.x == fromX && item.y == fromY) { break; }
var neighbors = this._getNeighbors(item.x, item.y);
for (var i=0;i<neighbors.length;i++) {
var neighbor = neighbors[i];
var x = neighbor[0];
var y = neighbor[1];
var id = x+","+y;
if (id in this._done) { continue; }
this._add(x, y, item);
}
}
var item = this._done[fromX+","+fromY];
if (!item) { return; }
while (item) {
callback(item.x, item.y);
item = item.prev;
}
}
ROT.Path.AStar.prototype._add = function(x, y, prev) {
var obj = {
x: x,
y: y,
prev: prev,
g: (prev ? prev.g+1 : 0),
h: this._distance(x, y)
}
this._done[x+","+y] = obj;
/* insert into priority queue */
var f = obj.g + obj.h;
for (var i=0;i<this._todo.length;i++) {
var item = this._todo[i];
if (f < item.g + item.h) {
this._todo.splice(i, 0, obj);
return;
}
}
this._todo.push(obj);
}
ROT.Path.AStar.prototype._distance = function(x, y) {
switch (this._options.topology) {
case 4:
return (Math.abs(x-this._fromX) + Math.abs(y-this._fromY));
break;
case 6:
var dx = Math.abs(x - this._fromX);
var dy = Math.abs(y - this._fromY);
return dy + Math.max(0, (dx-dy)/2);
break;
case 8:
return Math.max(Math.abs(x-this._fromX), Math.abs(y-this._fromY));
break;
}
}