diff --git a/TODO.md b/TODO.md
index 81cc7df..4991334 100644
--- a/TODO.md
+++ b/TODO.md
@@ -72,11 +72,11 @@ Ships models and actions
* Add a reflect damage effect
* Add untargettable effect (can only be targetted with area effects)
* Add damage modifier (to change the options of incoming damage or outgoing damage)
-* Add a balance testing page, using AI battles with or without an upgrade, to help in balancing
Artificial Intelligence
-----------------------
+* Account for overheated engines
* If web worker is not responsive, or produces only errors, it should be disabled for the session
* Produce interesting "angle" areas
* Evaluate active effects
@@ -85,7 +85,6 @@ Artificial Intelligence
* Use a first batch of producers, and only if no "good" move has been found, go on with some infinite producers
* Abandon fight if the AI judges there is no hope of victory
* Add combination of random small move and actual maneuver, as producer
-* New duel page with producers/evaluators tweaking
* Use tree techniques to account for potential future moves
* Prototype of evolving AI
diff --git a/out/ai.html b/out/ai.html
deleted file mode 100644
index 32aad32..0000000
--- a/out/ai.html
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
- SpaceTac - AI Duel
-
-
-
-
-
-
-
-
-
-
SpaceTac - AI Duel
-
-
-
-
-
-
- versus
-
-
-
-
-
-
- Start !
-
-
-
- Win
- Draw
- Win
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/out/sim.js b/out/sim.js
new file mode 100644
index 0000000..fa053da
--- /dev/null
+++ b/out/sim.js
@@ -0,0 +1,68 @@
+const Pool = require('process-pool').default;
+
+const pool = new Pool({ processLimit: 8 });
+const work = pool.prepare(function () {
+ const App = require("./build").TK.SpaceTac;
+
+ async function doOneBattle(i) {
+ let ai1 = new App.TacticalAI();
+ let ai2 = new App.TacticalAI();
+
+ // Prepare battle
+ let battle = App.Battle.newQuickRandom(true, 1, 2 + i % 4);
+ battle.fleets.forEach((fleet, findex) => {
+ fleet.ships.forEach((ship, sindex) => {
+ ship.name = `F${findex + 1}S${sindex + 1} (${ship.model.name})`;
+ });
+ });
+
+ // Run battle
+ while (!battle.ended && battle.cycle < 100) {
+ let playing = battle.playing_ship;
+ if (playing) {
+ let ai = (playing.fleet == battle.fleets[0]) ? ai1 : ai2;
+ ai.ship = playing;
+ await ai.play();
+ }
+ }
+
+ // Collect results
+ if (battle.outcome && battle.outcome.winner) {
+ let results = {};
+ battle.fleets.forEach(fleet => {
+ fleet.ships.forEach(ship => {
+ let name = `Level ${ship.level.get()} ${ship.model.name}`;
+ results[name] = (results[name] || 0) + (ship.fleet === battle.outcome.winner ? 1 : 0);
+ });
+ });
+ return results;
+ } else {
+ return {};
+ }
+ }
+
+ return (i) => doOneBattle(i);
+});
+
+let played = {};
+let winned = {};
+let works = Array.from({ length: 1000 }, (v, i) => i).map(i => {
+ return work(i).then(result => {
+ Object.keys(result).forEach(model => {
+ if (result[model]) {
+ winned[model] = (winned[model] || 0) + 1;
+ }
+ played[model] = (played[model] || 0) + 1;
+ });
+
+ console.warn("------------------------------------------------");
+ console.warn(`--- Results after battle ${i}`);
+ Object.keys(played).sort().forEach(model => {
+ let factor = (winned[model] || 0) / played[model];
+ console.warn(`${model} ${Math.round(factor * 100)}%`);
+ });
+ console.warn("------------------------------------------------");
+ });
+});
+
+Promise.all(works).then(() => process.exit(0));
diff --git a/package-lock.json b/package-lock.json
index 65e94eb..775a43e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -115,8 +115,7 @@
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
- "dev": true
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
},
"amqplib": {
"version": "0.5.2",
@@ -1019,6 +1018,7 @@
"requires": {
"anymatch": "1.3.2",
"async-each": "1.0.1",
+ "fsevents": "1.1.3",
"glob-parent": "2.0.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -2213,6 +2213,910 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
+ "fsevents": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
+ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "nan": "2.10.0",
+ "node-pre-gyp": "0.6.39"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "ajv": {
+ "version": "4.11.8",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "co": "4.6.0",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delegates": "1.0.0",
+ "readable-stream": "2.2.9"
+ }
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "bundled": true,
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.7",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "concat-map": "0.0.1"
+ }
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "co": {
+ "version": "4.6.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "debug": {
+ "version": "2.6.8",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.4.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "detect-libc": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "extsprintf": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.15"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "fstream": {
+ "version": "1.0.11",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "inherits": "2.0.3",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.1"
+ }
+ },
+ "fstream-ignore": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "fstream": "1.0.11",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4"
+ }
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aproba": "1.1.1",
+ "console-control-strings": "1.1.0",
+ "has-unicode": "2.0.1",
+ "object-assign": "4.1.1",
+ "signal-exit": "3.0.2",
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wide-align": "1.1.2"
+ }
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "bundled": true,
+ "dev": true
+ },
+ "har-schema": {
+ "version": "1.0.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "har-validator": {
+ "version": "4.2.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ajv": "4.11.8",
+ "har-schema": "1.0.5"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "bundled": true,
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.0",
+ "sshpk": "1.13.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "bundled": true,
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "jodid25519": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "jsprim": {
+ "version": "1.4.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.0.2",
+ "json-schema": "0.2.3",
+ "verror": "1.3.6"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "mime-db": {
+ "version": "1.27.0",
+ "bundled": true,
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.15",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "mime-db": "1.27.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true,
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "node-pre-gyp": {
+ "version": "0.6.39",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "detect-libc": "1.0.2",
+ "hawk": "3.1.3",
+ "mkdirp": "0.5.1",
+ "nopt": "4.0.1",
+ "npmlog": "4.1.0",
+ "rc": "1.2.1",
+ "request": "2.81.0",
+ "rimraf": "2.6.1",
+ "semver": "5.3.0",
+ "tar": "2.2.1",
+ "tar-pack": "3.4.0"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "abbrev": "1.1.0",
+ "osenv": "0.1.4"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "1.1.4",
+ "console-control-strings": "1.1.0",
+ "gauge": "2.7.4",
+ "set-blocking": "2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "performance-now": {
+ "version": "0.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "bundled": true,
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "qs": {
+ "version": "6.4.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "rc": {
+ "version": "1.2.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "deep-extend": "0.4.2",
+ "ini": "1.3.4",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.2.9",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "buffer-shims": "1.0.0",
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "string_decoder": "1.0.1",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "request": {
+ "version": "2.81.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "4.2.1",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.15",
+ "oauth-sign": "0.8.2",
+ "performance-now": "0.2.0",
+ "qs": "6.4.0",
+ "safe-buffer": "5.0.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "semver": {
+ "version": "5.3.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "sshpk": {
+ "version": "1.13.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jodid25519": "1.0.2",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.0.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "tar": {
+ "version": "2.2.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "block-stream": "0.0.9",
+ "fstream": "1.0.11",
+ "inherits": "2.0.3"
+ }
+ },
+ "tar-pack": {
+ "version": "3.4.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "2.6.8",
+ "fstream": "1.0.11",
+ "fstream-ignore": "1.0.5",
+ "once": "1.4.0",
+ "readable-stream": "2.2.9",
+ "rimraf": "2.6.1",
+ "tar": "2.2.1",
+ "uid-number": "0.0.6"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "uid-number": {
+ "version": "0.0.6",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "verror": {
+ "version": "1.3.6",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "extsprintf": "1.0.2"
+ }
+ },
+ "wide-align": {
+ "version": "1.1.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "string-width": "1.0.2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
"ftp": {
"version": "0.3.10",
"resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
@@ -2461,6 +3365,7 @@
"anymatch": "2.0.0",
"async-each": "1.0.1",
"braces": "2.3.1",
+ "fsevents": "1.1.3",
"glob-parent": "3.1.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
@@ -4500,6 +5405,13 @@
"integrity": "sha1-QCj3d4sXcIpImTCm5SrDvKDaQdA=",
"dev": true
},
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+ "dev": true,
+ "optional": true
+ },
"nanomatch": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
@@ -5270,6 +6182,37 @@
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"dev": true
},
+ "process-pool": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/process-pool/-/process-pool-0.3.5.tgz",
+ "integrity": "sha1-lrQKexzd2SRhu9Ygx2arCO1L7zc=",
+ "requires": {
+ "bluebird": "2.11.0",
+ "lodash": "3.10.1",
+ "rewire": "2.5.2",
+ "source-map": "0.4.4"
+ },
+ "dependencies": {
+ "bluebird": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
+ "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
+ },
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
"progress": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
@@ -5738,6 +6681,11 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"dev": true
},
+ "rewire": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/rewire/-/rewire-2.5.2.tgz",
+ "integrity": "sha1-ZCfee3/u+n02QBUH62SlOFvFjcc="
+ },
"right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
diff --git a/package.json b/package.json
index 77810ba..1523551 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"dependencies": {
"jasmine-core": "^3.1.0",
"parse": "^1.11.0",
- "phaser": "2.6.2"
+ "phaser": "2.6.2",
+ "process-pool": "^0.3.5"
}
-}
\ No newline at end of file
+}
diff --git a/src/MainUI.ts b/src/MainUI.ts
index 62c7b40..26537bc 100644
--- a/src/MainUI.ts
+++ b/src/MainUI.ts
@@ -1,9 +1,26 @@
///
if (typeof window != "undefined") {
+ // If jasmine is not present, ignore describe
(window).describe = (window).describe || function () { };
}
+declare var global: any;
+if (typeof global != "undefined") {
+ // In node, does not extend Phaser classes
+ var handler = {
+ get(target: any, name: any) {
+ return function () { }
+ }
+ }
+ global.Phaser = new Proxy({}, handler);
+}
+
+declare var module: any;
+if (typeof module != "undefined") {
+ module.exports = { TK };
+}
+
module TK.SpaceTac {
// Router between game views
export class MainUI extends Phaser.Game {
diff --git a/src/core/ai/AIDuel.ts b/src/core/ai/AIDuel.ts
deleted file mode 100644
index f4a1d82..0000000
--- a/src/core/ai/AIDuel.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-module TK.SpaceTac {
- /**
- * Duel between two AIs, over multiple battles
- */
- export class AIDuel {
- static current: AIDuel | null = null
-
- ai1: AbstractAI
- ai2: AbstractAI
- win1 = 0
- win2 = 0
- draw = 0
- scheduled = null
- stopped = false
- onupdate: Function | null = null
-
- constructor(ai1: AbstractAI, ai2: AbstractAI) {
- this.ai1 = ai1;
- this.ai2 = ai2;
- }
-
- /**
- * Start the duel
- */
- start(onupdate: Function | null = null) {
- if (!this.scheduled) {
- this.stopped = false;
- this.scheduled = Timer.global.schedule(100, () => this.next());
- this.onupdate = onupdate;
- }
- }
-
- /**
- * Stop the duel
- */
- stop() {
- this.stopped = true;
- if (this.scheduled) {
- Timer.global.cancel(this.scheduled);
- this.scheduled = null;
- }
- }
-
- /**
- * Update the result of a single battle
- */
- update(winner: number) {
- if (winner >= 0) {
- if (winner == 0) {
- this.win1 += 1;
- console.log(` => Player 1 wins (${this.ai1})`);
- } else {
- this.win2 += 1;
- console.log(` => Player 2 wins (${this.ai2})`);
- }
- } else {
- this.draw += 1;
- console.log(" => draw");
- }
-
- if (this.onupdate) {
- this.onupdate();
- }
- }
-
- /**
- * Perform the next battle
- */
- async next() {
- console.log(`${this.ai1.name} vs ${this.ai2.name} ...`);
-
- // Prepare battle
- let battle = Battle.newQuickRandom();
- battle.fleets.forEach((fleet, findex) => {
- fleet.ships.forEach((ship, sindex) => {
- ship.name = `F${findex + 1}S${sindex + 1} (${ship.model.name})`;
- });
- });
-
- // Run battle
- while (!battle.ended && battle.cycle < 100) {
- if (this.stopped) {
- return;
- }
-
- let playing = battle.playing_ship;
- if (playing) {
- let ai = (playing.fleet == battle.fleets[0]) ? this.ai1 : this.ai2;
- ai.ship = playing;
- await ai.play();
- }
- }
-
- // Update results, and go on to next battle
- if (battle.outcome && !battle.outcome.draw && battle.outcome.winner) {
- this.update(battle.fleets.indexOf(battle.outcome.winner));
- } else {
- this.update(-1);
- }
- this.scheduled = Timer.global.schedule(50, () => this.next());
- }
-
- /**
- * Setup the duel HTML page
- */
- static setup(element: HTMLElement) {
- let fakeship = new Ship();
- let ais = [new TacticalAI(fakeship), new AbstractAI(fakeship)];
- ais.forEach((ai, idx) => {
- let selects = element.getElementsByTagName("select");
- for (let i = 0; i < selects.length; i++) {
- let option = document.createElement("option");
- option.setAttribute("value", idx.toString());
- option.textContent = ai.name;
- selects[i].appendChild(option);
- }
- ai.name += `${idx + 1}`;
- ai.timer = new Timer();
- ai.timer.schedule = (delay, callback) => Timer.global.schedule(1, callback);
- });
-
- let button = element.getElementsByTagName("button").item(0);
- button.onclick = () => {
- if (AIDuel.current) {
- AIDuel.current.stop();
- AIDuel.current = null;
- button.textContent = "Start !";
- } else {
- console.clear();
- let ai1 = parseInt(element.getElementsByTagName("select").item(0).value);
- let ai2 = parseInt(element.getElementsByTagName("select").item(1).value);
- let duel = new AIDuel(ais[ai1], ais[ai2]);
- AIDuel.current = duel;
- duel.start(() => {
- element.getElementsByClassName("win1").item(0).textContent = duel.win1.toString();
- element.getElementsByClassName("win2").item(0).textContent = duel.win2.toString();
- element.getElementsByClassName("draw").item(0).textContent = duel.draw.toString();
- });
- button.textContent = "Stop !";
- }
- }
- }
- }
-}
diff --git a/tsconfig.json b/tsconfig.json
index b265a5f..5a2418c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,10 +11,9 @@
"sourceMap": true,
"lib": [
"dom",
- "es2015.promise",
- "es5"
+ "es6"
],
- "target": "es5"
+ "target": "es6"
},
"include": [
"src/**/*.ts"