From b27ac3ae87efacfa3a587d9eb5598992ce9e1c66 Mon Sep 17 00:00:00 2001 From: Scott Anderson <662325+scottanderson@users.noreply.github.com> Date: Thu, 3 Apr 2025 00:59:31 -0400 Subject: [PATCH] refactor tick --- src/core/execution/BotExecution.ts | 23 +++++++++++++++++------ src/core/execution/FakeHumanExecution.ts | 24 +++++++++++++----------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index b6fd7399f..90da61cd6 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -3,6 +3,7 @@ import { Game, Player, PlayerType, + Relation, TerraNullius, } from "../game/Game"; import { PseudoRandom } from "../PseudoRandom"; @@ -12,15 +13,15 @@ import { AttackExecution } from "./AttackExecution"; export class BotExecution implements Execution { private active = true; private random: PseudoRandom; - private attackRate: number; - private attackTick: number; + private updateRate: number; + private updateTick: number; private mg: Game; private neighborsTerraNullius = true; constructor(private bot: Player) { this.random = new PseudoRandom(simpleHash(bot.id())); - this.attackRate = this.random.nextInt(10, 50); - this.attackTick = this.random.nextInt(0, this.attackRate - 1); + this.updateRate = this.random.nextInt(10, 50); + this.updateTick = this.random.nextInt(0, this.updateRate); } activeDuringSpawnPhase(): boolean { return false; @@ -33,21 +34,31 @@ export class BotExecution implements Execution { } tick(ticks: number) { + if (ticks % this.updateRate != this.updateTick) return; + if (!this.bot.isAlive()) { this.active = false; return; } - if (ticks % this.attackRate != this.attackTick) return; + this.handleAllianceRequests(); + this.maybeAttack(); + } + private handleAllianceRequests() { this.bot.incomingAllianceRequests().forEach((ar) => { - if (ar.requestor().isTraitor()) { + if ( + ar.requestor().isTraitor() || + this.bot.relation(ar.requestor()) <= Relation.Distrustful + ) { ar.reject(); } else { ar.accept(); } }); + } + private maybeAttack() { const traitors = this.bot .neighbors() .filter((n) => n.isPlayer() && n.isTraitor()) as Player[]; diff --git a/src/core/execution/FakeHumanExecution.ts b/src/core/execution/FakeHumanExecution.ts index 43e3e997e..e286a0991 100644 --- a/src/core/execution/FakeHumanExecution.ts +++ b/src/core/execution/FakeHumanExecution.ts @@ -55,7 +55,7 @@ export class FakeHumanExecution implements Execution { simpleHash(playerInfo.id) + simpleHash(gameID), ); this.attackRate = this.random.nextInt(40, 80); - this.attackTick = this.random.nextInt(0, this.attackRate - 1); + this.attackTick = this.random.nextInt(0, this.attackRate); } init(mg: Game, ticks: number) { @@ -106,17 +106,18 @@ export class FakeHumanExecution implements Execution { } tick(ticks: number) { + if (ticks % this.attackRate != this.attackTick) return; + if (this.mg.inSpawnPhase()) { - if (ticks % this.random.nextInt(5, 30) == 0) { - const rl = this.randomLand(); - if (rl == null) { - consolex.warn(`cannot spawn ${this.playerInfo.name}`); - return; - } - this.mg.addExecution(new SpawnExecution(this.playerInfo, rl)); + const rl = this.randomLand(); + if (rl == null) { + consolex.warn(`cannot spawn ${this.playerInfo.name}`); + return; } + this.mg.addExecution(new SpawnExecution(this.playerInfo, rl)); return; } + if (this.player == null) { this.player = this.mg.players().find((p) => p.id() == this.playerInfo.id); if (this.player == null) { @@ -133,8 +134,6 @@ export class FakeHumanExecution implements Execution { return; } - if (ticks % this.attackRate != this.attackTick) return; - if ( this.player.troops() > 100_000 && this.player.targetTroopRatio() > 0.7 @@ -147,7 +146,10 @@ export class FakeHumanExecution implements Execution { this.handleEnemies(); this.handleUnits(); this.handleEmbargoesToHostileNations(); + this.maybeAttack(); + } + private maybeAttack() { const enemyborder = Array.from(this.player.borderTiles()) .flatMap((t) => this.mg.neighbors(t)) .filter( @@ -554,7 +556,7 @@ export class FakeHumanExecution implements Execution { return this.mg.unitInfo(type).cost(this.player); } - handleAllianceRequests() { + private handleAllianceRequests() { for (const req of this.player.incomingAllianceRequests()) { if (req.requestor().isTraitor()) { this.replyToAllianceRequest(req, false);