Merge pull request #44 from Krafpy/fix-sequence-parsing

Fix custom sequence parsing
This commit is contained in:
Nazar Misyats
2024-12-13 01:06:39 +01:00
committed by GitHub
5 changed files with 63 additions and 39 deletions

View File

@@ -264,10 +264,13 @@ export async function initEditorWithSystem(systems, systemIndex) {
systemSelector.disable();
try {
let sequence;
if (customSequence.value != "")
if (customSequence.value != "") {
sequence = FlybySequence.fromString(customSequence.value, system);
else
console.debug(sequence.seqStringFullNames);
}
else {
sequence = sequenceSelector.sequence;
}
updateAltitudeRange(depAltitude, sequence.bodies[0]);
const slen = sequence.length;
updateAltitudeRange(destAltitude, sequence.bodies[slen - 1]);
@@ -294,7 +297,7 @@ export async function initEditorWithSystem(systems, systemIndex) {
maxDurationSeconds = maxDuration.value * 24 * 3600;
}
}
console.log(maxDurationSeconds);
console.debug(maxDurationSeconds);
resetFoundTrajectory();
const userSettings = {
startDate: startDate,

View File

@@ -16,27 +16,33 @@ export class FlybySequence {
}
static fromString(str, system) {
str = str.trim();
const initials = str.split('-');
const initialsList = str.split('-').map(s => s.trim());
const ids = [];
let attractor = 0;
for (let i = 0; i < initials.length; i++) {
let valid = false;
let attractorId = 0;
for (let i = 0; i < initialsList.length; i++) {
const initials = initialsList[i];
if (initials.length < 2)
throw new Error("Body sequence initials must contain at least 2 characters.");
const bodiesWithInitials = [];
for (const body of system.orbiting) {
if (body.name.substring(0, 2) == initials[i]) {
if (i == 0) {
attractor = body.attractor.id;
}
else if (body.attractor.id != attractor) {
throw new Error("All bodies of the sequence must orbit around the same body.");
}
ids.push(body.id);
valid = true;
break;
if (body.name.toLowerCase().startsWith(initials.toLowerCase())) {
bodiesWithInitials.push(body);
}
}
if (!valid) {
throw new Error("Invalid custom sequence input.");
if (bodiesWithInitials.length >= 2) {
const bodyNames = bodiesWithInitials.map(body => body.name);
throw new Error(`Ambiguous initials \"${initials}\": ${joinStrings(bodyNames, ", ")}.`);
}
if (bodiesWithInitials.length == 0)
throw new Error(`Invalid custom sequence body initials \"${initials}\".`);
const body = bodiesWithInitials[0];
if (i == 0) {
attractorId = body.attractor.id;
}
else if (body.attractor.id != attractorId) {
throw new Error("All bodies of the sequence must orbit around the same body.");
}
ids.push(body.id);
}
if (ids.length <= 1) {
throw new Error("The sequence must contain at least two bodies.");

View File

@@ -359,7 +359,7 @@
The flyby sequence is the sequence of bodies encountered during the mission's
flight time. It starts with the departure body and ends with the destination body.
All intermediate bodies of the sequence are used for gravity assist. <br>
Sequences are represented using the first two characters of each body's name. For example, a mission
Sequences are represented using the first characters (at least two) of each body's name. For example, a mission
going from Kerbin to Jool, with a first flyby of Eve followed by a flyby of Duna would be written:
Ke-Ev-Du-Jo.
</p>

View File

@@ -343,10 +343,12 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
systemSelector.disable();
try {
let sequence: FlybySequence;
if(customSequence.value != "")
if(customSequence.value != "") {
sequence = FlybySequence.fromString(customSequence.value, system);
else
console.debug(sequence.seqStringFullNames);
} else {
sequence = sequenceSelector.sequence;
}
updateAltitudeRange(depAltitude, sequence.bodies[0]);
const slen = sequence.length;
@@ -378,7 +380,7 @@ export async function initEditorWithSystem(systems: SolarSystemData[], systemInd
maxDurationSeconds = maxDuration.value * 24*3600;
}
}
console.log(maxDurationSeconds);
console.debug(maxDurationSeconds);
resetFoundTrajectory();

View File

@@ -25,28 +25,41 @@ export class FlybySequence {
static fromString(str: string, system: SolarSystem){
str = str.trim();
const initials = str.split('-');
const initialsList = str.split('-').map(s => s.trim());
const ids: number[] = [];
let attractorId = 0;
let attractor = 0;
for(let i = 0; i < initialsList.length; i++) {
const initials = initialsList[i];
for(let i = 0; i < initials.length; i++){
let valid = false;
for(const body of system.orbiting){
if(body.name.substring(0, 2) == initials[i]){
if(i == 0) {
attractor = body.attractor.id;
} else if(body.attractor.id != attractor) {
throw new Error("All bodies of the sequence must orbit around the same body.");
}
ids.push(body.id);
valid = true;
break;
// at least 2 characters
if (initials.length < 2)
throw new Error("Body sequence initials must contain at least 2 characters.");
// check for ambiguity and validity
const bodiesWithInitials: OrbitingBody[] = [];
for (const body of system.orbiting) {
if (body.name.toLowerCase().startsWith(initials.toLowerCase())) {
bodiesWithInitials.push(body);
}
}
if(!valid){
throw new Error("Invalid custom sequence input.");
if (bodiesWithInitials.length >= 2) {
const bodyNames = bodiesWithInitials.map(body => body.name);
throw new Error(`Ambiguous initials \"${initials}\": ${joinStrings(bodyNames, ", ")}.`);
}
if (bodiesWithInitials.length == 0)
throw new Error(`Invalid custom sequence body initials \"${initials}\".`);
const body = bodiesWithInitials[0];
// check for same attractor
if (i == 0) {
attractorId = body.attractor.id;
} else if (body.attractor.id != attractorId) {
throw new Error("All bodies of the sequence must orbit around the same body.");
}
ids.push(body.id);
}
if(ids.length <= 1){