2020-07-23 11:00:46 +08:00
|
|
|
module es {
|
|
|
|
|
/**
|
|
|
|
|
* 计算路径给定的IUnweightedGraph和开始/目标位置
|
|
|
|
|
*/
|
|
|
|
|
export class BreadthFirstPathfinder {
|
2020-07-28 16:25:20 +08:00
|
|
|
public static search<T>(graph: IUnweightedGraph<T>, start: T, goal: T): T[] {
|
2020-07-23 11:00:46 +08:00
|
|
|
let foundPath = false;
|
|
|
|
|
let frontier = [];
|
|
|
|
|
frontier.unshift(start);
|
2020-06-10 12:23:19 +08:00
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
let cameFrom = new Map<T, T>();
|
|
|
|
|
cameFrom.set(start, start);
|
2020-06-10 12:23:19 +08:00
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
while (frontier.length > 0) {
|
2020-07-23 11:00:46 +08:00
|
|
|
let current = frontier.shift();
|
2020-07-28 16:25:20 +08:00
|
|
|
if (JSON.stringify(current) == JSON.stringify(goal)) {
|
2020-07-23 11:00:46 +08:00
|
|
|
foundPath = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graph.getNeighbors(current).forEach(next => {
|
2020-07-28 16:25:20 +08:00
|
|
|
if (!this.hasKey(cameFrom, next)) {
|
2020-07-23 11:00:46 +08:00
|
|
|
frontier.unshift(next);
|
|
|
|
|
cameFrom.set(next, current);
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-06-10 12:23:19 +08:00
|
|
|
}
|
|
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null;
|
2020-06-10 12:23:19 +08:00
|
|
|
}
|
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
private static hasKey<T>(map: Map<T, T>, compareKey: T) {
|
2020-07-23 11:00:46 +08:00
|
|
|
let iterator = map.keys();
|
|
|
|
|
let r: IteratorResult<T>;
|
|
|
|
|
while (r = iterator.next() , !r.done) {
|
|
|
|
|
if (JSON.stringify(r.value) == JSON.stringify(compareKey))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2020-06-10 12:23:19 +08:00
|
|
|
|
2020-07-23 11:00:46 +08:00
|
|
|
return false;
|
2020-06-10 12:23:19 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-07-23 11:00:46 +08:00
|
|
|
}
|