Replaced AI duel page with a node.js multi-process simulator
This commit is contained in:
parent
4838c74236
commit
095cf9e491
3
TODO.md
3
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
|
||||
|
||||
|
|
110
out/ai.html
110
out/ai.html
|
@ -1,110 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>SpaceTac - AI Duel</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
font-family: 'SpaceTac';
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'SpaceTac';
|
||||
src: url('fonts/daggersquare.regular.otf');
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #111;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 38px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
#duel {
|
||||
width: 50vw;
|
||||
margin-top: 30vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
font-size: 26px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background-color: #ddd;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 12px;
|
||||
width: 16vw;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
td:nth-child(1) {
|
||||
background-color: #611;
|
||||
}
|
||||
|
||||
td:nth-child(3) {
|
||||
background-color: #148;
|
||||
}
|
||||
|
||||
td[colspan] {
|
||||
background-color: inherit;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="vendor/phaser/phaser.min.js"></script>
|
||||
<script src="build.js"></script>
|
||||
|
||||
<div id="duel">
|
||||
<h1>SpaceTac - AI Duel</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<select></select>
|
||||
</td>
|
||||
<td>versus</td>
|
||||
<td>
|
||||
<select></select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<button>Start !</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Win</td>
|
||||
<td>Draw</td>
|
||||
<td>Win</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="win1"></td>
|
||||
<td class="draw"></td>
|
||||
<td class="win2"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function () {
|
||||
TK.SpaceTac.AIDuel.setup(document.getElementById("duel"));
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -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));
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
/// <reference path="lib/phaser.d.ts"/>
|
||||
|
||||
if (typeof window != "undefined") {
|
||||
// If jasmine is not present, ignore describe
|
||||
(<any>window).describe = (<any>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 {
|
||||
|
|
|
@ -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 !";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,10 +11,9 @@
|
|||
"sourceMap": true,
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2015.promise",
|
||||
"es5"
|
||||
"es6"
|
||||
],
|
||||
"target": "es5"
|
||||
"target": "es6"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
|
|
Loading…
Reference in New Issue