From fab17bd48a4ff3222a64a85a36d02bc10bd6013d Mon Sep 17 00:00:00 2001 From: evanpelle Date: Sun, 11 Aug 2024 17:57:24 -0700 Subject: [PATCH] bot attacks terranullius first --- TODO.txt | 1 + src/core/GameImpl.ts | 15 +++++++++---- src/core/execution/BotExecution.ts | 34 +++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/TODO.txt b/TODO.txt index a8d100545..0c19af172 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,6 +4,7 @@ * render player info efficiently DONE 8/11/2024 * better troop addition logic DONE 8/11/2024 * better expansion, add back directed expansion +* harder to expand on other players (defense) * use pastel theme for territories * improve front page * add username in front page diff --git a/src/core/GameImpl.ts b/src/core/GameImpl.ts index 1e455c193..dcb19082b 100644 --- a/src/core/GameImpl.ts +++ b/src/core/GameImpl.ts @@ -10,6 +10,7 @@ type CellString = string class TileImpl implements Tile { public _isBorder = false + private _neighbors: Tile[] = null constructor( private readonly gs: GameImpl, @@ -32,7 +33,10 @@ class TileImpl implements Tile { terrain(): TerrainType {return this._terrain} neighbors(): Tile[] { - return this.gs.neighbors(this) + if (this._neighbors == null) { + this._neighbors = this.gs.neighbors(this) + } + return this._neighbors } game(): Game {return this.gs} @@ -285,7 +289,6 @@ export class GameImpl implements MutableGame { } neighbors(tile: Tile): Tile[] { - this.assertIsOnMap(tile.cell()) const x = tile.cell().x const y = tile.cell().y const ns: TileImpl[] = [] @@ -338,7 +341,11 @@ export class GameImpl implements MutableGame { const tiles: Tile[] = [] tiles.push(tile) tile.neighbors().forEach(t => tiles.push(t)) - tiles.filter(t => t.hasOwner()).forEach(t => { + + for (const t of tiles) { + if (!t.hasOwner()) { + continue + } if (this.isBorder(t)) { (t.owner() as PlayerImpl)._borderTiles.set(t.cell().toString(), t); (t.owner() as PlayerImpl)._borderTileSet.add(t); @@ -348,7 +355,7 @@ export class GameImpl implements MutableGame { (t.owner() as PlayerImpl)._borderTileSet.delete(t); (t as TileImpl)._isBorder = false } - }) + } } isBorder(tile: Tile): boolean { diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index 0a4f94a25..893d004de 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -1,4 +1,4 @@ -import {Cell, Execution, MutableGame, MutablePlayer, PlayerID, PlayerInfo} from "../Game" +import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerInfo, TerraNullius} from "../Game" import {PseudoRandom} from "../PseudoRandom" import {AttackExecution} from "./AttackExecution"; @@ -8,6 +8,7 @@ export class BotExecution implements Execution { private random: PseudoRandom; private attackRate: number private gs: MutableGame + private neighborsTerra = true constructor(private bot: MutablePlayer) { @@ -17,6 +18,7 @@ export class BotExecution implements Execution { init(gs: MutableGame, ticks: number) { this.gs = gs + // this.neighborsTerra = this.bot.neighbors().filter(n => n == this.gs.terraNullius()).length > 0 } tick(ticks: number) { @@ -27,22 +29,38 @@ export class BotExecution implements Execution { if (ticks % this.attackRate == 0) { + if (this.neighborsTerra) { + for (const b of this.bot.borderTiles()) { + for (const n of b.neighbors()) { + if (n.owner() == this.gs.terraNullius()) { + this.sendAttack(this.gs.terraNullius()) + return + } + } + } + this.neighborsTerra = false + } + + const ns = this.bot.neighbors() if (ns.length == 0) { return } - const toAttack = ns[this.random.nextInt(0, ns.length)] + this.sendAttack(toAttack) - this.gs.addExecution(new AttackExecution( - this.bot.troops() / 100, - this.bot.id(), - toAttack.isPlayer() ? toAttack.id() : null, - null - )) } } + sendAttack(toAttack: Player | TerraNullius) { + this.gs.addExecution(new AttackExecution( + this.bot.troops() / 20, + this.bot.id(), + toAttack.isPlayer() ? toAttack.id() : null, + null + )) + } + owner(): MutablePlayer { return this.bot }