diff --git a/src/core/Game.ts b/src/core/Game.ts index b2a33df6e..987772eab 100644 --- a/src/core/Game.ts +++ b/src/core/Game.ts @@ -62,6 +62,7 @@ export interface Tile { owner(): Player | TerraNullius hasOwner(): boolean isBorder(): boolean + borders(other: Player | TerraNullius): boolean isInterior(): boolean cell(): Cell terrain(): Terrain @@ -102,6 +103,7 @@ export interface Player { isPlayer(): this is Player neighbors(): (Player | TerraNullius)[] numTilesOwned(): number + tiles(): ReadonlySet sharesBorderWith(other: Player | TerraNullius): boolean toString(): string } diff --git a/src/core/GameImpl.ts b/src/core/GameImpl.ts index 4178b5156..6680ab1b5 100644 --- a/src/core/GameImpl.ts +++ b/src/core/GameImpl.ts @@ -19,6 +19,15 @@ class TileImpl implements Tile { private readonly _terrain: TerrainType ) { } + borders(other: Player | TerraNullius): boolean { + for (const n of this.neighbors()) { + if (n.owner() == other) { + return true + } + } + return false + } + onShore(): boolean { return this.neighbors() .filter(t => t.terrain() == TerrainTypes.Water) @@ -78,7 +87,7 @@ export class PlayerImpl implements MutablePlayer { public _borderTileSet: Set = new Set() public _boats: BoatImpl[] = [] - public tiles: Map = new Map() + public _tiles: Map = new Map() constructor(private gs: GameImpl, public readonly _id: PlayerID, public readonly playerInfo: PlayerInfo, private _troops) { } @@ -103,7 +112,11 @@ export class PlayerImpl implements MutablePlayer { return false } numTilesOwned(): number { - return this.tiles.size + return this._tiles.size + } + + tiles(): ReadonlySet { + return new Set(this._tiles.values()) } borderTiles(): ReadonlySet { @@ -114,7 +127,7 @@ export class PlayerImpl implements MutablePlayer { const ns: Set<(MutablePlayer | TerraNullius)> = new Set() for (const border of this.borderTiles()) { for (const neighbor of border.neighbors()) { - if (neighbor.owner() != this) { + if (neighbor.terrain() == TerrainTypes.Land && neighbor.owner() != this) { ns.add((neighbor as TileImpl)._owner) } } @@ -131,13 +144,13 @@ export class PlayerImpl implements MutablePlayer { } isPlayer(): this is MutablePlayer {return true as const} - ownsTile(cell: Cell): boolean {return this.tiles.has(cell.toString())} + ownsTile(cell: Cell): boolean {return this._tiles.has(cell.toString())} setTroops(troops: number) {this._troops = Math.floor(troops)} conquer(tile: Tile) {this.gs.conquer(this, tile)} info(): PlayerInfo {return this.playerInfo} id(): PlayerID {return this._id} troops(): number {return this._troops} - isAlive(): boolean {return this.tiles.size > 0} + isAlive(): boolean {return this._tiles.size > 0} gameState(): MutableGame {return this.gs} executions(): Execution[] { return this.gs.executions().filter(exec => exec.owner().id() == this.id()) @@ -342,13 +355,13 @@ export class GameImpl implements MutableGame { const tileImpl = tile as TileImpl let previousOwner = tileImpl._owner if (previousOwner.isPlayer()) { - previousOwner.tiles.delete(tile.cell().toString()) + previousOwner._tiles.delete(tile.cell().toString()) previousOwner._borderTiles.delete(tile.cell().toString()) previousOwner._borderTileSet.delete(tile) tileImpl._isBorder = false } tileImpl._owner = owner - owner.tiles.set(tile.cell().toString(), tile) + owner._tiles.set(tile.cell().toString(), tile) this.updateBorders(tile) this.eventBus.emit(new TileEvent(tile)) } diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 9e3872b97..77b2994a5 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -8,7 +8,7 @@ export const defaultConfig = new class implements Config { return 50 } numBots(): number { - return 20 + return 500 } player(): PlayerConfig { return defaultPlayerConfig diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index 32cfcf7ce..dec8dbb1f 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -114,6 +114,23 @@ export class AttackExecution implements Execution { this.target.removeTroops(defenderTroopLoss) } this._owner.conquer(tileToConquer) + if (this.target.isPlayer() && this.target.numTilesOwned() < 100) { + for (let i = 0; i < 10; i++) { + for (const tile of this.target.tiles()) { + if (tile.borders(this._owner)) { + this._owner.conquer(tile) + } else { + for (const neighbor of tile.neighbors()) { + const no = neighbor.owner() + if (no.isPlayer() && no != this.target) { + this.mg.player(no.id()).conquer(tile) + break + } + } + } + } + } + } } } @@ -144,7 +161,7 @@ export class AttackExecution implements Execution { if (numOwnedByMe > 2) { numOwnedByMe = 1000 } - this.toConquer.add(new TileContainer(neighbor, dist + -numOwnedByMe + (tile.cell().x * tile.cell().y) % 2)) + this.toConquer.add(new TileContainer(neighbor, dist + -numOwnedByMe)) } } this.borderTiles = newBorder