From ca5cc497638d588df689cad979491bf65cdd1746 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Sat, 10 Aug 2024 11:32:06 -0700 Subject: [PATCH] working --- TODO.txt | 2 +- src/client/GameRenderer.ts | 2 - src/core/GameImpl.ts | 157 ++++++++++++++--------------- src/core/execution/BotExecution.ts | 2 +- 4 files changed, 78 insertions(+), 85 deletions(-) diff --git a/TODO.txt b/TODO.txt index d8c9b3502..4c58e5803 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,5 @@ * fix conquer expansion DONE -* perf improvements on graphics (only draw images to canvas on ticks) +* perf improvements on graphics (only draw images to canvas on ticks) DONE * double join lobby bug * improve front page * make boats larger diff --git a/src/client/GameRenderer.ts b/src/client/GameRenderer.ts index d7ed065a2..0db84b268 100644 --- a/src/client/GameRenderer.ts +++ b/src/client/GameRenderer.ts @@ -192,8 +192,6 @@ export class GameRenderer { } paintTile(tile: Tile) { - // const index = (tile.cell().y * this.gs.width()) + tile.cell().x - // color.toRGB().writeToBuffer(this.imageData.data, index * 4) let terrainColor = this.theme.terrainColor(tile.terrain()) this.paintCell(tile.cell(), terrainColor) const owner = tile.owner() diff --git a/src/core/GameImpl.ts b/src/core/GameImpl.ts index 52b6c7701..f55dab4a2 100644 --- a/src/core/GameImpl.ts +++ b/src/core/GameImpl.ts @@ -69,6 +69,9 @@ export class BoatImpl implements MutableBoat { class Border { borderWith: Map> = new Map() + public _borderTiles: Map = new Map() + + constructor(private gs: GameImpl, private player: Player | TerraNullius) { } sharesBorderWith(other: Player | TerraNullius): boolean { if (!this.borderWith.has(other)) { @@ -76,17 +79,66 @@ class Border { } return this.borderWith.get(other).size > 0 } + + addCalcBorderWithTile(tile: Tile) { + this.gs.neighbors(tile.cell()).map(c => this.gs.tile(c)).forEach(t => { + this.insertBorderWithTile(tile, t.owner()) + }) + } + + removeCalcBorderWithTile(tile: Tile, oldNeighbor: Player | TerraNullius) { + const length = this.gs.neighbors(tile.cell()).map(c => this.gs.tile(c)).filter(t => t.owner() == oldNeighbor).length + if (length == 0) { + this.deleteBorderWithTile(tile, oldNeighbor) + } + } + + insertBorderWithTile(tile: Tile, player: Player | TerraNullius) { + if (!this.borderWith.has(player)) { + this.borderWith.set(player, new Set()) + } + if (player != this.player && tile.terrain() == TerrainTypes.Land) { + this.borderWith.get(player).add(tile) + } + } + + deleteBorderWithTile(tile: Tile, player: Player | TerraNullius) { + if (!this.borderWith.has(player)) { + this.borderWith.set(player, new Set()) + } + this.borderWith.get(player).delete(tile) + } + updateBorderWithTile(tile: Tile, oldOwner: Player | TerraNullius, newOwner: Player | TerraNullius) { + if (!this.borderWith.has(oldOwner)) { + this.borderWith.set(oldOwner, new Set()) + } + if (!this.borderWith.has(newOwner)) { + this.borderWith.set(newOwner, new Set()) + } + + // Delete old neighbors + if (this.gs.tileNeighbors(tile).filter(t => t.owner() == newOwner).length == 0) { + this.borderWith.get(oldOwner).delete(tile) + } + } + + borderTiles(): ReadonlySet { + return new Set(this._borderTiles.values()) + } + borderTilesWith(other: Player | TerraNullius): ReadonlySet { + return this.borderWith.get(other) || new Set(); + } } export class PlayerImpl implements MutablePlayer { public _boats: BoatImpl[] = [] - - public _borderTiles: Map = new Map() - _borderWith: Map> = new Map() public tiles: Map = new Map() + public border: Border - constructor(private gs: GameImpl, public readonly _id: PlayerID, public readonly playerInfo: PlayerInfo, private _troops) { } + constructor(private gs: GameImpl, public readonly _id: PlayerID, public readonly playerInfo: PlayerInfo, private _troops) { + this.border = new Border(gs, this) + } addBoat(troops: number, cell: Cell, target: Player | TerraNullius): BoatImpl { const b = new BoatImpl(this.gs, cell, troops, this, target as PlayerImpl | TerraNulliusImpl) @@ -98,22 +150,19 @@ export class PlayerImpl implements MutablePlayer { return this._boats } sharesBorderWith(other: Player | TerraNullius): boolean { - if (!this._borderWith.has(other)) { - return false - } - return this._borderWith.get(other).size > 0 + return this.border.sharesBorderWith(other) } numTilesOwned(): number { return this.tiles.size } borderTiles(): ReadonlySet { - return new Set(this._borderTiles.values()) + return this.border.borderTiles() } neighbors(): (MutablePlayer | TerraNullius)[] { const ns: (MutablePlayer | TerraNullius)[] = [] - for (const [player, tiles] of this._borderWith) { + for (const [player, tiles] of this.border.borderWith) { if (tiles.size > 0) { ns.push(player as MutablePlayer) } @@ -140,60 +189,19 @@ export class PlayerImpl implements MutablePlayer { executions(): Execution[] { return this.gs.executions().filter(exec => exec.owner().id() == this.id()) } - borderTilesWith(other: Player | TerraNullius): ReadonlySet { - return this._borderWith.get(other) || new Set(); - } - - updateBorderWithTile(tile: Tile, oldOwner: Player | TerraNullius, newOwner: Player | TerraNullius) { - if (!this._borderWith.has(oldOwner)) { - this._borderWith.set(oldOwner, new Set()) - } - if (!this._borderWith.has(newOwner)) { - this._borderWith.set(newOwner, new Set()) - } - - // Delete old neighbors - if (this.gs.tileNeighbors(tile).filter(t => t.owner() == newOwner).length == 0) { - this._borderWith.get(oldOwner).delete(tile) - } - } - - addCalcBorderWithTile(tile: Tile) { - this.gs.neighbors(tile.cell()).map(c => this.gs.tile(c)).forEach(t => { - this.insertBorderWithTile(tile, t.owner()) - }) - } - - removeCalcBorderWithTile(tile: Tile, oldNeighbor: Player | TerraNullius) { - const length = this.gs.neighbors(tile.cell()).map(c => this.gs.tile(c)).filter(t => t.owner() == oldNeighbor).length - if (length == 0) { - this.deleteBorderWithTile(tile, oldNeighbor) - } - } - - insertBorderWithTile(tile: Tile, player: Player | TerraNullius) { - if (!this._borderWith.has(player)) { - this._borderWith.set(player, new Set()) - } - if (player != this) { - this._borderWith.get(player).add(tile) - } - } - - deleteBorderWithTile(tile: Tile, player: Player | TerraNullius) { - if (!this._borderWith.has(player)) { - this._borderWith.set(player, new Set()) - } - this._borderWith.get(player).delete(tile) + return this.border.borderTilesWith(other) } } class TerraNulliusImpl implements TerraNullius { - _borderWith: Map> = new Map() public tiles: Map = new Map() + public border: Border - constructor(private gs: MutableGame) { } + + constructor(private gs: GameImpl) { + this.border = new Border(gs, this) + } id(): PlayerID { return 0 @@ -204,19 +212,11 @@ class TerraNulliusImpl implements TerraNullius { isPlayer(): false {return false as const} borderTilesWith(other: Player): ReadonlySet { - const border = new Set() - for (const enemyBorder of other.borderTilesWith(this)) { - for (const neighbor of enemyBorder.neighbors()) { - if (neighbor.terrain() == TerrainTypes.Land && neighbor.owner() == this) { - border.add(neighbor) - } - } - } - return border + return this.border.borderTilesWith(other) } sharesBorderWith(other: Player): boolean { - return other.sharesBorderWith(this) + return this.border.sharesBorderWith(other) } } @@ -349,12 +349,13 @@ export class GameImpl implements MutableGame { neighbors(cell: Cell): Cell[] { this.assertIsOnMap(cell) - return [ + const ns = [ new Cell(cell.x + 1, cell.y), new Cell(cell.x - 1, cell.y), new Cell(cell.x, cell.y + 1), new Cell(cell.x, cell.y - 1) ].filter(c => this.isOnMap(c)) + return ns } tileNeighbors(tile: Tile): Tile[] { @@ -378,7 +379,7 @@ export class GameImpl implements MutableGame { let previousOwner = tile._owner if (previousOwner.isPlayer()) { previousOwner.tiles.delete(cell.toString()) - previousOwner._borderTiles.delete(cell.toString()) + previousOwner.border._borderTiles.delete(cell.toString()) } tile._owner = owner owner.tiles.set(cell.toString(), tile) @@ -393,9 +394,9 @@ export class GameImpl implements MutableGame { this.neighbors(cell).forEach(c => cells.push(c)) cells.map(c => this.tile(c)).filter(c => c.hasOwner()).forEach(t => { if (this.isBorder(t)) { - (t.owner() as PlayerImpl)._borderTiles.set(t.cell().toString(), t) + (t.owner() as PlayerImpl).border._borderTiles.set(t.cell().toString(), t) } else { - (t.owner() as PlayerImpl)._borderTiles.delete(t.cell().toString()) + (t.owner() as PlayerImpl).border._borderTiles.delete(t.cell().toString()) } }) } @@ -404,19 +405,13 @@ export class GameImpl implements MutableGame { const newOwner = tile._owner const neighbors = this.neighbors(tile.cell()).map(c => this.tile(c)) - if (newOwner.isPlayer()) { - newOwner.addCalcBorderWithTile(tile) - } + newOwner.border.addCalcBorderWithTile(tile) neighbors.map(t => (t as TileImpl)).forEach(t => { const p = t._owner - if (p.isPlayer()) { - p.addCalcBorderWithTile(t) - p.removeCalcBorderWithTile(t, previousOwner) - } - if (previousOwner.isPlayer()) { - previousOwner.deleteBorderWithTile(tile, p) - } + p.border.addCalcBorderWithTile(t) + p.border.removeCalcBorderWithTile(t, previousOwner) + previousOwner.border.deleteBorderWithTile(tile, p) }) } diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index d3e091526..f451ad949 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -35,7 +35,7 @@ export class BotExecution implements Execution { const toAttack = ns[this.random.nextInt(0, ns.length)] this.gs.addExecution(new AttackExecution( - this.bot.troops() / 5, + this.bot.troops() / 15, this.bot.id(), toAttack.isPlayer() ? toAttack.id() : null, null