1
0
Fork 0

[node] Implemented multi hops in system navigation

This commit is contained in:
Julien Dessaux 2024-04-07 23:04:38 +02:00
parent 3e80bc8a4d
commit 91d394dfc9
Signed by: adyxax
GPG key ID: F92E51B86E07177E
2 changed files with 68 additions and 11 deletions

View file

@ -1,4 +1,9 @@
import { Cargo, CargoManifest } from './types.ts';
import { PriorityQueue } from './priority_queue.ts';
import {
Cargo,
CargoManifest,
Waypoint,
} from './types.ts';
export type CategorizedCargo = {
wanted: CargoManifest;
@ -45,6 +50,47 @@ export function sortByDistanceFrom<T extends Point>(a: Point, points: Array<T>):
return result;
}
type Step = {waypoint: Waypoint, prev: string, fuel: number, total: number};
type ShortestPath = Array<{symbol: string, fuel: number}>;
export function shortestPath(origin: Waypoint, destination: Waypoint, range: number, waypoints: Array<Waypoint>): ShortestPath {
let backtrace: {[key: string]: Step} = {};
let fuels: {[key: string]: number} = {}; // fuel = distance + 1 per hop
let unvisited: {[key: string]: Waypoint} = {};
waypoints.forEach(function(w) {
fuels[w.symbol] = Infinity;
unvisited[w.symbol] = w;
});
fuels[origin.symbol] = 0;
let queue = new PriorityQueue();
queue.enqueue({waypoint: origin, prev: origin.symbol, fuel: 0, total: 0}, 0);
while(!queue.isEmpty()) {
let step = queue.dequeue() as Step;
const symbol = step.waypoint.symbol;
if (!(symbol in unvisited)) continue;
backtrace[symbol] = step;
if (symbol === destination.symbol) break;
const prev = unvisited[symbol];
delete unvisited[symbol];
for(const ws in unvisited) {
const w = unvisited[ws];
const f = distance(prev, w) + 1;
if (f > range) continue;
const total = step.fuel + f;
if (fuels[ws] > total) {
fuels[ws] = total;
queue.enqueue({waypoint: w, prev: symbol, fuel: f, total: total}, total);
}
}
}
let result: ShortestPath = [];
for (let step = backtrace[destination.symbol]; step.waypoint.symbol != origin.symbol; step = backtrace[step.prev]) {
if (step === undefined) throw `Cannot compute shortest path from ${origin.symbol} to ${destination.symbol} with range ${range}.`;
result.push({symbol: step.waypoint.symbol, fuel: step.fuel});
}
return result;
}
export function systemFromWaypoint(waypoint: string): string {
return waypoint.split('-').slice(0,2).join('-');
}