From f9fddeb7c662f92d5101f89a64fcbb15d97e0ddb Mon Sep 17 00:00:00 2001 From: evanpelle Date: Wed, 7 Aug 2024 20:54:20 -0700 Subject: [PATCH] fix directed expansion --- TODO.txt | 5 ++- src/client/ClientGame.ts | 20 +++++---- src/core/execution/AttackExecution.ts | 63 +++++++++++++++++++++------ src/core/execution/BotExecution.ts | 6 +-- 4 files changed, 65 insertions(+), 29 deletions(-) diff --git a/TODO.txt b/TODO.txt index 53113337d..d8c9b3502 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,8 @@ -* fix conquer expansion +* fix conquer expansion DONE +* perf improvements on graphics (only draw images to canvas on ticks) +* double join lobby bug * improve front page * make boats larger -* perf improvements on graphics (only draw images to canvas on ticks) * better troop addition logic * maybe cache neigbors? * have boats not get close to shore diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index 14e41d3ac..753a4f4a6 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -42,6 +42,8 @@ export class ClientGame { private ticksThisTurn = 0 private currTurn = 0 + private spawned = false + constructor( private playerName: string, private id: ClientID, @@ -94,7 +96,7 @@ export class ClientGame { this.renderer.initialize() this.input.initialize() - this.executor.spawnBots(500) + // this.executor.spawnBots(500) setInterval(() => this.tick(), 10); @@ -130,12 +132,16 @@ export class ClientGame { private inputEvent(event: MouseDownEvent) { const cell = this.renderer.screenToWorldCoordinates(event.x, event.y) - const tile = this.gs.tile(cell) - if (!tile.hasOwner() && !this.hasSpawned()) { - this.sendSpawnIntent(cell) + if (!this.gs.isOnMap(cell)) { return } - if (!this.hasSpawned()) { + const tile = this.gs.tile(cell) + if (!tile.hasOwner() && !this.spawned && this.myPlayer == null) { + this.sendSpawnIntent(cell) + this.spawned = true + return + } + if (!this.spawned || this.myPlayer == null) { return } @@ -153,10 +159,6 @@ export class ClientGame { } - private hasSpawned(): boolean { - return this.myPlayer != null - } - private sendSpawnIntent(cell: Cell) { const spawn = JSON.stringify( ClientIntentMessageSchema.parse({ diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index 3ec74694d..700143e34 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -11,6 +11,8 @@ export class AttackExecution implements Execution { private _owner: MutablePlayer private target: MutablePlayer | TerraNullius + private mg: MutableGame + constructor( private troops: number, private _ownerID: PlayerID, @@ -23,21 +25,32 @@ export class AttackExecution implements Execution { this.target = this.targetID == null ? gs.terraNullius() : gs.player(this.targetID) this.troops = Math.min(this._owner.troops(), this.troops) this._owner.setTroops(this._owner.troops() - this.troops) + this.mg = gs } tick(ticks: number) { if (!this.active) { return } + // const t = this.mg.tile(new Cell(0, 0)) + // this.toConquer.add(new TileContainer(t, 4)) + // this.toConquer.add(new TileContainer(t, 1)) + // this.toConquer.add(new TileContainer(t, 2)) + // this.toConquer.add(new TileContainer(t, 3)) - let numTilesPerTick = this._owner.borderTilesWith(this.target).size / 2 + // while (this.toConquer.size() > 0) { + // console.log(`!!! got ${this.toConquer.poll().priority}`) + // } + + + let numTilesPerTick = this._owner.borderTilesWith(this.target).size while (numTilesPerTick > 0) { if (this.troops < 1) { this.active = false return } - if (this.toConquer.size() == 0) { + if (this.toConquer.size() < this._owner.borderTilesWith(this.target).size / 1.5) { this.calculateToConquer() } if (this.toConquer.size() == 0) { @@ -46,7 +59,8 @@ export class AttackExecution implements Execution { return } - const tileToConquer: Tile = this.toConquer.poll().tile + const toConquerContainer = this.toConquer.poll() + const tileToConquer: Tile = toConquerContainer.tile const onBorder = tileToConquer.neighbors().filter(t => t.owner() == this._owner).length > 0 if (tileToConquer.owner() != this.target || !onBorder) { continue @@ -77,21 +91,42 @@ export class AttackExecution implements Execution { // } // tileByDist.forEach(t => console.log(`tile dist: ${manhattanDist(t.cell(), closestTile.cell())}`)) - let tileByDist = [] - if (this.targetCell == null) { - tileByDist = Array.from(enemyBorder).slice().sort((a, b) => this.random.next() - .5) - } else { - tileByDist = Array.from(enemyBorder).slice().sort((a, b) => manhattanDist(a.cell(), this.targetCell) - manhattanDist(b.cell(), this.targetCell)) + // let tileByDist = [] + // if (this.targetCell == null) { + // tileByDist = Array.from(enemyBorder).slice().sort((a, b) => this.random.next() - .5) + // } else { + // } + // for (let i = 0; i < Math.min(enemyBorder.size / 2, tileByDist.length); i++) { + // const enemyTile = tileByDist[i] + // const numOwnedByMe = enemyTile.neighbors() + // .filter(t => t.terrain() == TerrainTypes.Land) + // .filter(t => t.owner() == this._owner) + // .length + // // this.toConquer.add(new TileContainer(enemyTile, numOwnedByMe + (this.random.next() % 5) + (-5 * i / tileByDist.length))) + // const r = this.random.next() % 4 + // this.toConquer.add(new TileContainer(enemyTile, r + numOwnedByMe * 1000)) + // } + this.toConquer.clear() + + let tiles = Array.from(enemyBorder) + + if (this.targetCell != null) { + tiles = tiles.slice().sort((a, b) => manhattanDist(a.cell(), this.targetCell) - manhattanDist(b.cell(), this.targetCell)) } - for (let i = 0; i < Math.min(enemyBorder.size / 2, tileByDist.length); i++) { - const enemyTile = tileByDist[i] - const numOwnedByMe = enemyTile.neighbors() + + + for (let i = 0; i < tiles.length; i++) { + const numOwnedByMe = tiles[i].neighbors() .filter(t => t.terrain() == TerrainTypes.Land) .filter(t => t.owner() == this._owner) .length - // this.toConquer.add(new TileContainer(enemyTile, numOwnedByMe + (this.random.next() % 5) + (-5 * i / tileByDist.length))) - const r = this.random.next() % 4 - this.toConquer.add(new TileContainer(enemyTile, r + numOwnedByMe * 1000)) + + let distModifer = 0 + if (this.targetCell != null) { + distModifer = i / tiles.length * 2 + } + this.toConquer.add(new TileContainer(tiles[i], distModifer - numOwnedByMe + this.random.nextInt(0, 2))) + // this.toConquer.add(new TileContainer(tiles[i], i)) } } diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index 19e0557ff..d3e091526 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -3,7 +3,6 @@ import {PseudoRandom} from "../PseudoRandom" import {AttackExecution} from "./AttackExecution"; export class BotExecution implements Execution { - private ticks = 0 private active = true private random: PseudoRandom; @@ -13,7 +12,7 @@ export class BotExecution implements Execution { constructor(private bot: MutablePlayer) { this.random = new PseudoRandom(bot.id()) - this.attackRate = this.random.nextInt(100, 500) + this.attackRate = this.random.nextInt(50, 200) } init(gs: MutableGame, ticks: number) { @@ -26,9 +25,8 @@ export class BotExecution implements Execution { return } - this.ticks++ - if (this.ticks % this.attackRate == 0) { + if (ticks % this.attackRate == 0) { const ns = this.bot.neighbors() if (ns.length == 0) { return