diff --git a/TODO b/TODO index 5b93534..78eed35 100644 --- a/TODO +++ b/TODO @@ -44,6 +44,8 @@ * AI: apply safety distances to move actions * AI: add combination of random small move and actual maneuver, as producer * AI: new duel page with producers/evaluators tweaking +* AI: work in a dedicated process +* AI: evaluate area effects at ship location * Map: remove jump links that cross the radius of other systems * Map: disable interaction (zoom, selection) while moving/jumping * Tutorial diff --git a/src/core/ai/Maneuver.ts b/src/core/ai/Maneuver.ts index bfe56f2..17e8faa 100644 --- a/src/core/ai/Maneuver.ts +++ b/src/core/ai/Maneuver.ts @@ -39,6 +39,13 @@ module TS.SpaceTac { return `Use ${this.action.code} on ${this.target.jasmineToString()}`; } + /** + * Returns true if the maneuver cannot be fully done this turn + */ + isIncomplete(): boolean { + return (this.simulation.need_move && !this.simulation.can_end_move) || (this.simulation.need_fire && !this.simulation.can_fire); + } + /** * Apply the maneuver in current battle */ diff --git a/src/core/ai/TacticalAI.ts b/src/core/ai/TacticalAI.ts index f90db61..db1151f 100644 --- a/src/core/ai/TacticalAI.ts +++ b/src/core/ai/TacticalAI.ts @@ -19,14 +19,16 @@ module TS.SpaceTac { private best: Maneuver | null private best_score: number - protected initWork(delay?: number): void { + private last_action = new Date().getTime() + + protected initWork(): void { this.best = null; this.best_score = -Infinity; this.producers = this.getDefaultProducers(); this.evaluators = this.getDefaultEvaluators(); - this.addWorkItem(() => this.unitWork(), delay); + this.addWorkItem(() => this.unitWork()); } /** @@ -44,8 +46,9 @@ module TS.SpaceTac { */ private unitWork() { let done = 0; + let started = new Date().getTime(); - while (done < 1000 && this.producers.length > 0) { + while (this.producers.length > 0 && (new Date().getTime() - started < 50)) { // Produce a maneuver let maneuver: Maneuver | null = null; let producer = this.producers.shift(); @@ -72,13 +75,17 @@ module TS.SpaceTac { // Continue or stop if (this.producers.length > 0 && this.getDuration() < 8000) { - this.addWorkItem(() => this.unitWork()); + this.addWorkItem(() => this.unitWork(), 10); } else if (this.best) { - console.log("AI maneuver", this.best, this.best_score); - this.best.apply(); - if (this.ship.playing) { - this.initWork(2000); - } + let best_maneuver = this.best; + console.log("AI maneuver", best_maneuver, this.best_score); + this.addWorkItem(() => { + this.last_action = new Date().getTime(); + best_maneuver.apply(); + if (this.ship.playing && !best_maneuver.isIncomplete()) { + this.initWork(); + } + }, Math.max(0, 2000 - (new Date().getTime() - this.last_action))); } } @@ -104,8 +111,8 @@ module TS.SpaceTac { let evaluators = [ scaled(TacticalAIHelpers.evaluateTurnCost, 1), scaled(TacticalAIHelpers.evaluateOverheat, 10), - scaled(TacticalAIHelpers.evaluateEnemyHealth, 100), - scaled(TacticalAIHelpers.evaluateAllyHealth, 200), + scaled(TacticalAIHelpers.evaluateEnemyHealth, 500), + scaled(TacticalAIHelpers.evaluateAllyHealth, 800), scaled(TacticalAIHelpers.evaluateClustering, 3), scaled(TacticalAIHelpers.evaluatePosition, 1), scaled(TacticalAIHelpers.evaluateIdling, 1), diff --git a/src/ui/battle/BattleView.ts b/src/ui/battle/BattleView.ts index adc2467..274d94e 100644 --- a/src/ui/battle/BattleView.ts +++ b/src/ui/battle/BattleView.ts @@ -127,6 +127,7 @@ module TS.SpaceTac.UI { this.inputs.bindCheat("a", "Use AI to play", () => { if (this.interacting && this.battle.playing_ship) { this.setInteractionEnabled(false); + this.action_bar.setShip(new Ship()); this.battle.playAI(new TacticalAI(this.battle.playing_ship)); } }); @@ -214,6 +215,7 @@ module TS.SpaceTac.UI { // Enable or disable the global player interaction // Disable interaction when it is the AI turn, or when the current ship can't play setInteractionEnabled(enabled: boolean): void { + this.action_bar.setInteractive(enabled); this.exitTargettingMode(); this.interacting = enabled; } diff --git a/src/ui/battle/LogProcessor.ts b/src/ui/battle/LogProcessor.ts index c54aedb..d0eff48 100644 --- a/src/ui/battle/LogProcessor.ts +++ b/src/ui/battle/LogProcessor.ts @@ -141,7 +141,6 @@ module TS.SpaceTac.UI { // AI turn this.view.gameui.audio.playOnce("battle-ship-change"); this.battle.playAI(); - this.delayNextEvents(1500); } else { // Ship unable to play, skip turn this.view.timer.schedule(event.new_ship.alive ? 2000 : 200, () => {