made attack execution more efficient

This commit is contained in:
evanpelle
2024-08-11 20:32:19 -07:00
parent 47fa978c35
commit fe52f6035d
4 changed files with 78 additions and 87 deletions
+4 -1
View File
@@ -4,8 +4,11 @@
* render player info efficiently DONE 8/11/2024
* better troop addition logic DONE 8/11/2024
* better expansion, add back directed expansion DONE 8/11/2024
* use pastel theme for territories
* use pastel theme for territories DONE 8/11/2024
* cache border in AttackExecution for perf
* harder to expand on other players (defense)
* lose troops when attacked
* fix boat bugs
* add username in front page
* improve front page
* upload and start server
+2 -8
View File
@@ -85,13 +85,11 @@ export class NameRenderer {
const centerX = box.min.x + ((box.max.x - box.min.x) / 2)
const centerY = box.min.y + ((box.max.y - box.min.y) / 2)
render.location = new Cell(centerX, centerY)
render.fontSize = Math.max(Math.min(box.max.x - box.min.x, box.max.y - box.min.y) / render.player.info().name.length / 2, 2)
render.fontSize = Math.max(Math.min(box.max.x - box.min.x, box.max.y - box.min.y) / render.player.info().name.length / 2, 1.5)
return wasUpdated
}
renderPlayerInfo(render: RenderInfo, context: CanvasRenderingContext2D, scale: number, uppperLeft: Cell, bottomRight: Cell) {
// console.log(`scale: ${scale}, fontSize: ${render.fontSize}, mult: ${scale * render.fontSize}`)
if (render.fontSize * scale < 10) {
return
}
@@ -103,18 +101,14 @@ export class NameRenderer {
return
}
// if (nameCenterX, ) {
// }
context.textRendering = "optimizeSpeed";
context.font = `${render.fontSize}px Arial`;
context.font = `bold ${render.fontSize}px ${this.theme.font()}`;
context.fillStyle = this.theme.playerInfoColor(render.player.id()).toHex();
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText(render.player.info().name, nameCenterX, nameCenterY - render.fontSize / 2);
context.fillText(String(Math.floor(render.player.troops())), nameCenterX, nameCenterY + render.fontSize);
}
+57 -11
View File
@@ -17,7 +17,6 @@ export interface Theme {
terrainColor(tile: TerrainType): Colord;
backgroundColor(): Colord;
font(): string;
shaderArgs(): {name: string; args: {[key: string]: any}}[];
}
export const defaultSettings = new class implements Settings {
@@ -45,21 +44,72 @@ const pastelTheme = new class implements Theme {
private land = colord({r: 244, g: 243, b: 198});
private water = colord({r: 160, g: 203, b: 231});
private territory = colord({r: 173, g: 216, b: 230});
private territoryColors: Colord[] = [
colord({r: 255, g: 179, b: 186}), // Vibrant Light Pink
colord({r: 255, g: 223, b: 186}), // Vibrant Peach
colord({r: 190, g: 255, b: 190}), // Vibrant Light Green
colord({r: 173, g: 216, b: 255}), // Vibrant Light Blue
colord({r: 224, g: 187, b: 255}), // Vibrant Light Purple
colord({r: 255, g: 191, b: 230}), // Vibrant Pink
colord({r: 210, g: 255, b: 210}), // Vibrant Mint Green
colord({r: 255, g: 213, b: 179}), // Vibrant Light Orange
colord({r: 198, g: 198, b: 255}), // Vibrant Lavender
colord({r: 255, g: 255, b: 186}), // Vibrant Light Yellow
colord({r: 186, g: 255, b: 201}), // Vibrant Seafoam Green
colord({r: 255, g: 186, b: 255}), // Vibrant Light Magenta
colord({r: 210, g: 255, b: 210}), // Vibrant Pale Green
colord({r: 255, g: 202, b: 202}), // Vibrant Salmon Pink
colord({r: 206, g: 206, b: 255}), // Vibrant Periwinkle
colord({r: 255, g: 234, b: 186}), // Vibrant Cream
colord({r: 186, g: 255, b: 255}), // Vibrant Light Cyan
colord({r: 238, g: 210, b: 255}), // Vibrant Lilac
colord({r: 206, g: 255, b: 238}), // Vibrant Pale Turquoise
colord({r: 255, g: 209, b: 186}), // Vibrant Peach
colord({r: 186, g: 216, b: 255}), // Vibrant Baby Blue
colord({r: 246, g: 255, b: 186}), // Vibrant Pale Yellow
colord({r: 220, g: 186, b: 255}), // Vibrant Light Violet
colord({r: 255, g: 186, b: 213}), // Vibrant Rose
colord({r: 186, g: 255, b: 226}), // Vibrant Honeydew
colord({r: 206, g: 236, b: 255}), // Vibrant Sky Blue
colord({r: 255, g: 232, b: 206}), // Vibrant Wheat
colord({r: 206, g: 255, b: 255}), // Vibrant Pale Cyan
colord({r: 255, g: 216, b: 216}), // Vibrant Misty Rose
colord({r: 216, g: 216, b: 255}), // Vibrant Pale Lavender
colord({r: 255, g: 250, b: 205}), // Vibrant Pale Goldenrod
colord({r: 216, g: 255, b: 216}), // Vibrant Pale Mint
colord({r: 255, g: 216, b: 255}), // Vibrant Pale Plum
colord({r: 220, g: 255, b: 220}), // Vibrant Mint Cream
colord({r: 255, g: 220, b: 220}), // Vibrant Pale Pink
colord({r: 220, g: 220, b: 255}), // Vibrant Pale Blue
colord({r: 255, g: 255, b: 220}), // Vibrant Light Goldenrod
colord({r: 220, g: 255, b: 255}), // Vibrant Light Azure
colord({r: 255, g: 220, b: 255}), // Vibrant Pale Magenta
colord({r: 230, g: 255, b: 230}), // Vibrant Honeydew
colord({r: 255, g: 230, b: 230}), // Vibrant Lavender Blush
colord({r: 230, g: 230, b: 255}), // Vibrant Ghost White
colord({r: 255, g: 239, b: 219}), // Vibrant Seashell
colord({r: 219, g: 255, b: 239}), // Vibrant Mint Cream
colord({r: 239, g: 219, b: 255}), // Vibrant Pale Lavender
colord({r: 255, g: 250, b: 230}), // Vibrant Floral White
colord({r: 230, g: 255, b: 250}), // Vibrant Azure Mist
colord({r: 250, g: 230, b: 255}), // Vibrant Pale Purple
colord({r: 250, g: 255, b: 230}), // Vibrant Ivory
colord({r: 230, g: 250, b: 255}) // Vibrant Alice Blue
];
playerInfoColor(id: PlayerID): Colord {
return colord({r: 0, g: 0, b: 0})
}
territoryColor(id: PlayerID): Colord {
return colord({r: (id * 10) % 250, g: (id * 100) % 250, b: (id) % 250});
return this.territoryColors[id % this.territoryColors.length]
}
borderColor(id: PlayerID): Colord {
const tc = this.territoryColor(id).rgba;
return colord({
r: Math.min(tc.r + 20, 255),
g: Math.min(tc.g + 20, 255),
b: Math.min(tc.b + 20, 255)
r: Math.max(tc.r - 20, 0),
g: Math.max(tc.g - 20, 0),
b: Math.max(tc.b - 20, 0)
})
}
@@ -75,10 +125,6 @@ const pastelTheme = new class implements Theme {
}
font(): string {
return "Overpass";
}
shaderArgs(): {name: string; args: {[key: string]: any}}[] {
throw new Error("Method not implemented.");
return "Arial";
}
}
+15 -67
View File
@@ -14,6 +14,7 @@ export class AttackExecution implements Execution {
private mg: MutableGame
private numTilesWithEnemy = 0
private borderTiles: Set<Tile> = new Set()
constructor(
private troops: number,
@@ -35,31 +36,22 @@ export class AttackExecution implements Execution {
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))
// while (this.toConquer.size() > 0) {
// console.log(`!!! got ${this.toConquer.poll().priority}`)
// }
let numTilesPerTick = this.numTilesWithEnemy / 2
let numTilesPerTick = this.numTilesWithEnemy / 4
if (this.targetCell != null) {
numTilesPerTick /= 2
}
let badTiles = 0
while (numTilesPerTick > 0) {
if (this.troops < 1) {
this.active = false
return
}
if (this.toConquer.size() < this.numTilesWithEnemy / 2) {
if (this.toConquer.size() < this.numTilesWithEnemy / 1.5) {
this.calculateToConquer()
}
if (this.toConquer.size() == 0) {
if (this.toConquer.size() == 0 || badTiles > 100) {
this.active = false
this._owner.addTroops(this.troops)
return
@@ -69,6 +61,7 @@ export class AttackExecution implements Execution {
const tileToConquer: Tile = toConquerContainer.tile
const onBorder = tileToConquer.neighbors().filter(t => t.owner() == this._owner).length > 0
if (tileToConquer.owner() != this.target || !onBorder) {
badTiles++
continue
}
this._owner.conquer(tileToConquer)
@@ -79,62 +72,21 @@ export class AttackExecution implements Execution {
private calculateToConquer() {
this.numTilesWithEnemy = 0
// console.profile('calc_to_conquer')
// let closestTile: Tile;
// let closestDist: number = Number.POSITIVE_INFINITY;
// for (const enemyTile of enemyBorder) {
// const dist = manhattanDist(enemyTile.cell(), this.targetCell)
// if (dist < closestDist) {
// closestTile = enemyTile
// }
// }
// 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 {
// }
// 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()
// if (this.targetCell != null) {
// let tiles = Array.from(enemyBorder)
// tiles = tiles.slice().sort((a, b) => manhattanDist(a.cell(), this.targetCell) - manhattanDist(b.cell(), this.targetCell))
// 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
// 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))
// }
// } else {
for (const tile of this._owner.borderTiles()) {
const newBorder: Set<Tile> = new Set()
let existingBorder: ReadonlySet<Tile> = this.borderTiles
if (existingBorder.size == 0) {
existingBorder = this._owner.borderTiles()
}
for (const tile of existingBorder) {
for (const neighbor of tile.neighbors()) {
if (neighbor.terrain() == TerrainTypes.Water || neighbor.owner() != this.target) {
continue
}
newBorder.add(neighbor)
this.numTilesWithEnemy += 1
const numOwnedByMe = tile.neighbors()
let numOwnedByMe = tile.neighbors()
.filter(t => t.terrain() == TerrainTypes.Land)
.filter(t => t.owner() == this._owner)
.length
@@ -145,11 +97,7 @@ export class AttackExecution implements Execution {
this.toConquer.add(new TileContainer(neighbor, dist + -numOwnedByMe + (tile.cell().x * tile.cell().y) % 2))
}
}
// }
// console.profileEnd('calc_to_conquer')
this.borderTiles = newBorder
}
owner(): MutablePlayer {