From e0e10d9e40da5ed811c9eafb224d7f710adc9bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 9 Jul 2017 18:00:37 +0200 Subject: [PATCH] Removed redundant jump links between stars --- TODO.md | 2 +- src/common | 2 +- src/core/MoveFireSimulator.ts | 3 +-- src/core/Star.ts | 16 ++++++------ src/core/Universe.spec.ts | 23 +++++++++++++++++ src/core/Universe.ts | 45 ++++++++++++++++++++++++++++----- src/multi/RemoteStorage.spec.ts | 2 +- 7 files changed, 73 insertions(+), 20 deletions(-) diff --git a/TODO.md b/TODO.md index 934dda3..fdc9048 100644 --- a/TODO.md +++ b/TODO.md @@ -11,10 +11,10 @@ Map/story --------- * 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 * Enemy fleet size should start low and increase with system level * 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 factions and reputation * Add generated missions with rewards diff --git a/src/common b/src/common index 1905bfa..95eb6e8 160000 --- a/src/common +++ b/src/common @@ -1 +1 @@ -Subproject commit 1905bfa0d1bb53d21c2ee6537fe2551c13d8dbbe +Subproject commit 95eb6e8e69bace0fcc40392c04b0af96ffdffd3c diff --git a/src/core/MoveFireSimulator.ts b/src/core/MoveFireSimulator.ts index 83bb60f..984da5f 100644 --- a/src/core/MoveFireSimulator.ts +++ b/src/core/MoveFireSimulator.ts @@ -60,8 +60,7 @@ module TS.SpaceTac { if (engines.length == 0) { return null; } 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 engines[0]; + return maxBy(engines, engine => (engine.action instanceof MoveAction) ? engine.action.distance_per_power : 0); } } diff --git a/src/core/Star.ts b/src/core/Star.ts index bade1ef..1e3f7e5 100644 --- a/src/core/Star.ts +++ b/src/core/Star.ts @@ -128,11 +128,11 @@ module TS.SpaceTac { return warp; } - // Get the number of links to other stars - getLinks(): StarLink[] { + // Get all direct links to other stars + getLinks(all = this.universe.starlinks): StarLink[] { var result: StarLink[] = []; - this.universe.starlinks.forEach((link: StarLink) => { + all.forEach(link => { if (link.first === this || link.second === this) { result.push(link); } @@ -141,11 +141,11 @@ module TS.SpaceTac { return result; } - // Get the link to another star, null of not found - getLinkTo(other: Star): StarLink | null { + // Get the link to another star, null if not found + getLinkTo(other: Star, all = this.universe.starlinks): StarLink | null { var result: StarLink | null = null; - this.universe.starlinks.forEach(link => { + all.forEach(link => { if (link.isLinking(this, other)) { result = link; } @@ -170,8 +170,8 @@ module TS.SpaceTac { /** * Get the neighboring star systems (single jump accessible) */ - getNeighbors(): Star[] { - return nna(this.getLinks().map(link => link.getPeer(this))); + getNeighbors(all = this.universe.starlinks): Star[] { + return nna(this.getLinks(all).map(link => link.getPeer(this))); } // Check if a location is far enough from all other ones diff --git a/src/core/Universe.spec.ts b/src/core/Universe.spec.ts index 11d329a..06175f6 100644 --- a/src/core/Universe.spec.ts +++ b/src/core/Universe.spec.ts @@ -32,6 +32,29 @@ module TS.SpaceTac.Specs { var filtered = universe.filterCrossingLinks(result); 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", () => { diff --git a/src/core/Universe.ts b/src/core/Universe.ts index 5257d5d..6fa4b03 100644 --- a/src/core/Universe.ts +++ b/src/core/Universe.ts @@ -18,8 +18,8 @@ module TS.SpaceTac { /** * Add a single star */ - addStar(level = 1, name?: string): Star { - let result = new Star(this, 0, 0, name || `Star ${this.stars.length + 1}`); + addStar(level = 1, name?: string, x = 0, y = 0): Star { + let result = new Star(this, x, y, name || `Star ${this.stars.length + 1}`); result.level = level; this.stars.push(result); return result; @@ -42,7 +42,7 @@ module TS.SpaceTac { this.stars = this.generateStars(starcount); let links = this.getPotentialLinks(); - this.starlinks = this.filterCrossingLinks(links); + this.starlinks = this.filterRedundantLinks(this.filterCrossingLinks(links)); } this.generateWarpLocations(); @@ -98,7 +98,12 @@ module TS.SpaceTac { 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[] { var result: StarLink[] = []; @@ -117,6 +122,33 @@ module TS.SpaceTac { 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 generateWarpLocations() { this.starlinks.forEach(link => { @@ -216,9 +248,8 @@ module TS.SpaceTac { * Get a good start location */ getStartLocation(): StarLocation { - let stars = acopy(this.stars); - stars.sort((a, b) => cmp(a.level, b.level)); - return stars[0].locations[0]; + let star = minBy(this.stars, star => star.level); + return star.locations[0]; } } } diff --git a/src/multi/RemoteStorage.spec.ts b/src/multi/RemoteStorage.spec.ts index c8b81ef..832adcb 100644 --- a/src/multi/RemoteStorage.spec.ts +++ b/src/multi/RemoteStorage.spec.ts @@ -45,7 +45,7 @@ module TS.SpaceTac.Multi.Specs { await storage.upsert("test", { key: 5, text: "things" }, {}); 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" }]); }); }); } \ No newline at end of file