62 lines
1.6 KiB
JavaScript
62 lines
1.6 KiB
JavaScript
/**
|
|
* Node - Represents a pathfinding node in the D* Lite algorithm
|
|
* Each node wraps a Point and stores pathfinding metadata
|
|
*/
|
|
import { Point } from './Point.js';
|
|
|
|
export class Node {
|
|
constructor(point) {
|
|
this.point = point;
|
|
this.key = point.toKey();
|
|
|
|
// D* Lite values
|
|
this.g = Infinity; // Cost from start to this node
|
|
this.rhs = Infinity; // One-step lookahead cost
|
|
|
|
// Whether this node is blocked (wall, unbreakable block, etc.)
|
|
this.blocked = false;
|
|
|
|
// Whether this node contains a mineable block (costs more to traverse but possible)
|
|
this.mineable = false;
|
|
|
|
// The block data at this position (if known)
|
|
this.blockData = null;
|
|
}
|
|
|
|
/**
|
|
* Calculate the D* Lite key pair for priority queue ordering
|
|
* @param {Point} start - The current start position
|
|
* @param {number} km - The key modifier (updated on robot movement)
|
|
*/
|
|
calculateKey(start, km = 0) {
|
|
const minVal = Math.min(this.g, this.rhs);
|
|
return [
|
|
minVal + start.euclideanDistanceTo(this.point) + km,
|
|
minVal
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check if this node is consistent (g === rhs)
|
|
*/
|
|
isConsistent() {
|
|
return this.g === this.rhs;
|
|
}
|
|
|
|
/**
|
|
* Get the traversal cost to move to this node
|
|
* - Blocked nodes: Infinity
|
|
* - Mineable blocks: 2 (higher cost to prefer open paths)
|
|
* - Open space: 1
|
|
*/
|
|
getTraversalCost() {
|
|
if (this.blocked) return Infinity;
|
|
if (this.mineable) return 2;
|
|
return 1;
|
|
}
|
|
|
|
toString() {
|
|
return `Node(${this.point}, g=${this.g}, rhs=${this.rhs}, blocked=${this.blocked})`;
|
|
}
|
|
}
|