Removed redundant jump links between stars
This commit is contained in:
parent
0feba35db0
commit
e0e10d9e40
2
TODO.md
2
TODO.md
|
@ -11,10 +11,10 @@ Map/story
|
||||||
---------
|
---------
|
||||||
|
|
||||||
* Add initial character creation
|
* Add initial character creation
|
||||||
* Remove jump links that cross the radius of other systems
|
|
||||||
* Fix quickly zooming in twice preventing to display some UI parts
|
* Fix quickly zooming in twice preventing to display some UI parts
|
||||||
* Enemy fleet size should start low and increase with system level
|
* Enemy fleet size should start low and increase with system level
|
||||||
* Allow to change/buy ship model
|
* Allow to change/buy ship model
|
||||||
|
* Fix galaxy generator sometimes being short on systems to create a proper level gradient (mainly in unit testing)
|
||||||
* Add ship personality (with icons to identify ?), with reaction dialogs
|
* Add ship personality (with icons to identify ?), with reaction dialogs
|
||||||
* Add factions and reputation
|
* Add factions and reputation
|
||||||
* Add generated missions with rewards
|
* Add generated missions with rewards
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1905bfa0d1bb53d21c2ee6537fe2551c13d8dbbe
|
Subproject commit 95eb6e8e69bace0fcc40392c04b0af96ffdffd3c
|
|
@ -60,8 +60,7 @@ module TS.SpaceTac {
|
||||||
if (engines.length == 0) {
|
if (engines.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
engines.sort((a, b) => (a.action instanceof MoveAction && b.action instanceof MoveAction) ? cmp(b.action.distance_per_power, a.action.distance_per_power) : 0);
|
return maxBy(engines, engine => (engine.action instanceof MoveAction) ? engine.action.distance_per_power : 0);
|
||||||
return engines[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,11 +128,11 @@ module TS.SpaceTac {
|
||||||
return warp;
|
return warp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the number of links to other stars
|
// Get all direct links to other stars
|
||||||
getLinks(): StarLink[] {
|
getLinks(all = this.universe.starlinks): StarLink[] {
|
||||||
var result: StarLink[] = [];
|
var result: StarLink[] = [];
|
||||||
|
|
||||||
this.universe.starlinks.forEach((link: StarLink) => {
|
all.forEach(link => {
|
||||||
if (link.first === this || link.second === this) {
|
if (link.first === this || link.second === this) {
|
||||||
result.push(link);
|
result.push(link);
|
||||||
}
|
}
|
||||||
|
@ -141,11 +141,11 @@ module TS.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the link to another star, null of not found
|
// Get the link to another star, null if not found
|
||||||
getLinkTo(other: Star): StarLink | null {
|
getLinkTo(other: Star, all = this.universe.starlinks): StarLink | null {
|
||||||
var result: StarLink | null = null;
|
var result: StarLink | null = null;
|
||||||
|
|
||||||
this.universe.starlinks.forEach(link => {
|
all.forEach(link => {
|
||||||
if (link.isLinking(this, other)) {
|
if (link.isLinking(this, other)) {
|
||||||
result = link;
|
result = link;
|
||||||
}
|
}
|
||||||
|
@ -170,8 +170,8 @@ module TS.SpaceTac {
|
||||||
/**
|
/**
|
||||||
* Get the neighboring star systems (single jump accessible)
|
* Get the neighboring star systems (single jump accessible)
|
||||||
*/
|
*/
|
||||||
getNeighbors(): Star[] {
|
getNeighbors(all = this.universe.starlinks): Star[] {
|
||||||
return nna(this.getLinks().map(link => link.getPeer(this)));
|
return nna(this.getLinks(all).map(link => link.getPeer(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a location is far enough from all other ones
|
// Check if a location is far enough from all other ones
|
||||||
|
|
|
@ -32,6 +32,29 @@ module TS.SpaceTac.Specs {
|
||||||
|
|
||||||
var filtered = universe.filterCrossingLinks(result);
|
var filtered = universe.filterCrossingLinks(result);
|
||||||
expect(filtered.length).toBe(5);
|
expect(filtered.length).toBe(5);
|
||||||
|
expect(any(filtered, link => link.isLinking(universe.stars[1], universe.stars[2]))).toBe(true);
|
||||||
|
expect(any(filtered, link => link.isLinking(universe.stars[0], universe.stars[3]))).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("filters out redundant links", () => {
|
||||||
|
let universe = new Universe();
|
||||||
|
let s1 = universe.addStar(1, "S1", 0, 0);
|
||||||
|
let s2 = universe.addStar(1, "S2", 0, 1);
|
||||||
|
let s3 = universe.addStar(1, "S3", 1, 0);
|
||||||
|
let s4 = universe.addStar(1, "S4", 0.75, 0.75);
|
||||||
|
|
||||||
|
let links = [
|
||||||
|
new StarLink(s1, s2),
|
||||||
|
new StarLink(s1, s3),
|
||||||
|
new StarLink(s2, s3),
|
||||||
|
new StarLink(s2, s4),
|
||||||
|
new StarLink(s3, s4),
|
||||||
|
]
|
||||||
|
|
||||||
|
let filtered = universe.filterRedundantLinks(links);
|
||||||
|
expect(filtered.length).toBe(4);
|
||||||
|
expect(filtered).toContain(links[0]);
|
||||||
|
expect(filtered).not.toContain(links[2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("generates warp locations", () => {
|
it("generates warp locations", () => {
|
||||||
|
|
|
@ -18,8 +18,8 @@ module TS.SpaceTac {
|
||||||
/**
|
/**
|
||||||
* Add a single star
|
* Add a single star
|
||||||
*/
|
*/
|
||||||
addStar(level = 1, name?: string): Star {
|
addStar(level = 1, name?: string, x = 0, y = 0): Star {
|
||||||
let result = new Star(this, 0, 0, name || `Star ${this.stars.length + 1}`);
|
let result = new Star(this, x, y, name || `Star ${this.stars.length + 1}`);
|
||||||
result.level = level;
|
result.level = level;
|
||||||
this.stars.push(result);
|
this.stars.push(result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -42,7 +42,7 @@ module TS.SpaceTac {
|
||||||
this.stars = this.generateStars(starcount);
|
this.stars = this.generateStars(starcount);
|
||||||
|
|
||||||
let links = this.getPotentialLinks();
|
let links = this.getPotentialLinks();
|
||||||
this.starlinks = this.filterCrossingLinks(links);
|
this.starlinks = this.filterRedundantLinks(this.filterCrossingLinks(links));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.generateWarpLocations();
|
this.generateWarpLocations();
|
||||||
|
@ -98,7 +98,12 @@ module TS.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter a list of potential links to avoid crossing ones
|
/**
|
||||||
|
* Filter a list of potential links to avoid crossing ones.
|
||||||
|
*
|
||||||
|
* Returned list of links should be free of crossings.
|
||||||
|
* This should not alter the universe connectivity.
|
||||||
|
*/
|
||||||
filterCrossingLinks(links: StarLink[]): StarLink[] {
|
filterCrossingLinks(links: StarLink[]): StarLink[] {
|
||||||
var result: StarLink[] = [];
|
var result: StarLink[] = [];
|
||||||
|
|
||||||
|
@ -117,6 +122,33 @@ module TS.SpaceTac {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a list of potential links to remove redundant ones.
|
||||||
|
*
|
||||||
|
* This will remove direct links that are also achieved by a similar two-jump couple.
|
||||||
|
* This should not alter the universe connectivity.
|
||||||
|
*/
|
||||||
|
filterRedundantLinks(links: StarLink[]): StarLink[] {
|
||||||
|
let result: StarLink[] = [];
|
||||||
|
|
||||||
|
links = sortedBy(links, link => link.getLength(), true);
|
||||||
|
|
||||||
|
links.forEach(link => {
|
||||||
|
let alternative_passages = intersection(
|
||||||
|
link.first.getNeighbors(links).filter(n => n != link.second),
|
||||||
|
link.second.getNeighbors(links).filter(n => n != link.first)
|
||||||
|
);
|
||||||
|
let alternative_lengths = alternative_passages.map(
|
||||||
|
passage => nn(link.first.getLinkTo(passage, links)).getLength() + nn(link.second.getLinkTo(passage, links)).getLength()
|
||||||
|
);
|
||||||
|
if (!any(alternative_lengths, length => length < link.getLength() * 1.2)) {
|
||||||
|
result.push(link);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate warp locations for the links between stars
|
// Generate warp locations for the links between stars
|
||||||
generateWarpLocations() {
|
generateWarpLocations() {
|
||||||
this.starlinks.forEach(link => {
|
this.starlinks.forEach(link => {
|
||||||
|
@ -216,9 +248,8 @@ module TS.SpaceTac {
|
||||||
* Get a good start location
|
* Get a good start location
|
||||||
*/
|
*/
|
||||||
getStartLocation(): StarLocation {
|
getStartLocation(): StarLocation {
|
||||||
let stars = acopy(this.stars);
|
let star = minBy(this.stars, star => star.level);
|
||||||
stars.sort((a, b) => cmp(a.level, b.level));
|
return star.locations[0];
|
||||||
return stars[0].locations[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ module TS.SpaceTac.Multi.Specs {
|
||||||
await storage.upsert("test", { key: 5, text: "things" }, {});
|
await storage.upsert("test", { key: 5, text: "things" }, {});
|
||||||
|
|
||||||
result = await storage.search("test", { key: 5 });
|
result = await storage.search("test", { key: 5 });
|
||||||
expect(result.sort((a: any, b: any) => cmp(a.text, b.text))).toEqual([{ key: 5, text: "other thingy" }, { key: 5, text: "things" }]);
|
expect(sortedBy(result, (x: any) => x.text)).toEqual([{ key: 5, text: "other thingy" }, { key: 5, text: "things" }]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
Loading…
Reference in a new issue