From 60751150bf4e03eb18490864fba15ecfb859c971 Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 3 Nov 2024 20:11:04 -0800 Subject: [PATCH] added gold, troops, workers slider --- resources/maps/WorldMap.json | 2 +- src/client/graphics/layers/ControlPanel.ts | 86 ++++++++++++++++++---- src/core/configuration/Config.ts | 4 +- src/core/configuration/DefaultConfig.ts | 28 +++---- src/core/execution/ExecutionManager.ts | 1 + src/core/execution/FakeHumanExecution.ts | 2 +- src/core/execution/PlayerExecution.ts | 7 +- src/core/game/Game.ts | 21 +++--- src/core/game/PlayerImpl.ts | 77 +++++++++---------- 9 files changed, 143 insertions(+), 85 deletions(-) diff --git a/resources/maps/WorldMap.json b/resources/maps/WorldMap.json index dde4813e3..15efccfb1 100644 --- a/resources/maps/WorldMap.json +++ b/resources/maps/WorldMap.json @@ -48,7 +48,7 @@ 593, 473 ], - "name": "Venezuala 🇻🇪", + "name": "Venezuela 🇻🇪", "strength": 1 }, { diff --git a/src/client/graphics/layers/ControlPanel.ts b/src/client/graphics/layers/ControlPanel.ts index a82322d0b..4e2955700 100644 --- a/src/client/graphics/layers/ControlPanel.ts +++ b/src/client/graphics/layers/ControlPanel.ts @@ -3,9 +3,10 @@ import { customElement, property, state } from 'lit/decorators.js'; import { Layer } from './Layer'; import { Game } from '../../../core/game/Game'; import { ClientID } from '../../../core/Schemas'; -import { renderTroops } from '../Utils'; +import { renderNumber, renderTroops } from '../Utils'; import { EventBus } from '../../../core/EventBus'; import { UIState } from '../UIState'; +import { SendSetTargetTroopRatioEvent } from '../../Transport'; @customElement('control-panel') export class ControlPanel extends LitElement implements Layer { @@ -15,20 +16,39 @@ export class ControlPanel extends LitElement implements Layer { public uiState: UIState @state() - private targetTroopRatio = 50; + private attackRatio: number = .2; + + @state() + private targetTroopRatio = 1; + + @state() + private _population: number; + + @state() + private _maxPopulation: number; + + @state() + private popRate: number; @state() private _troops: number; @state() - private _maxTroops: number; - - @state() - private troopRate: number; + private _workers: number; @state() private _isVisible = false; + @state() + private _manpower: number = 0; + + @state() + private _gold: number + + + @state() + private _goldPerSecond: number + init(game: Game) { this.game = game; this.attackRatio = .20 @@ -43,10 +63,16 @@ export class ControlPanel extends LitElement implements Layer { const player = this.game.playerByClientID(this.clientID) if (player == null) { + this._isVisible = false return } + this._population = player.population() + this._maxPopulation = this.game.config().maxPopulation(player) + this._gold = player.gold() this._troops = player.troops() - this._maxTroops = this.game.config().maxTroops(player) + this._workers = player.workers() + this.popRate = this.game.config().populationIncreaseRate(player) * 10 + this._goldPerSecond = this.game.config().goldAdditionRate(player) * 10 } onAttackRatioChange(newRatio: number) { @@ -67,7 +93,19 @@ export class ControlPanel extends LitElement implements Layer { } targetTroops(): number { - return this._manpower * this.targetTroopRatio / 100 + return this._manpower * this.targetTroopRatio + } + + onTroopChange(newRatio: number) { + this.eventBus.emit(new SendSetTargetTroopRatioEvent(newRatio)) + } + + delta(): number { + const d = this._population - this.targetTroops() + // if (Math.abs(d) < this._manpower / 200) { + // return 0 + // } + return d } @@ -129,16 +167,36 @@ export class ControlPanel extends LitElement implements Layer {
- Troops: - ${renderTroops(this._troops)} / ${renderTroops(this._maxTroops)} + Population: + ${renderTroops(this._population)} / ${renderTroops(this._maxPopulation)} +
+
+ Population/s: + ${renderTroops(this.popRate)} +
+
+ Gold: + ${renderNumber(this._gold)} +
+
+ Gold/s: + ${renderNumber(this._goldPerSecond)}
- - Troops: ${renderTroops(this._troops)} | Workers: ${renderTroops(this._workers)} + { - this.targetTroopRatio = parseInt((e.target as HTMLInputElement).value); - this.onTroopChange(this.targetTroopRatio / 100); + this.targetTroopRatio = parseInt((e.target as HTMLInputElement).value) / 10; + this.onTroopChange(this.targetTroopRatio); + }}> +
+
+ + { + this.attackRatio = parseInt((e.target as HTMLInputElement).value) / 10; + this.onAttackRatioChange(this.attackRatio); }}>
diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index 895f18b59..1a1b868af 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -34,7 +34,7 @@ export interface Config { numSpawnPhaseTurns(): number startManpower(playerInfo: PlayerInfo): number - manpowerAdditionRate(player: Player): number + populationIncreaseRate(player: Player): number goldAdditionRate(player: Player): number troopAdjustmentRate(player: Player): number attackTilesPerTick(attacker: Player, defender: Player | TerraNullius, numAdjacentTilesWithEnemy: number): number @@ -44,7 +44,7 @@ export interface Config { tilesPerTickUsed: number } attackAmount(attacker: Player, defender: Player | TerraNullius): number - maxManpower(player: Player): number + maxPopulation(player: Player): number boatAttackAmount(attacker: Player, defender: Player | TerraNullius): number boatMaxDistance(): number boatMaxNumber(): number diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 2a6d53e6f..ceef2e7d4 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -130,21 +130,20 @@ export class DefaultConfig implements Config { return 25000 } - maxManpower(player: Player): number { - let max = Math.sqrt(player.numTilesOwned()) * 3000 + 50000 - const manpower = Math.min(max, 2_000_000) + maxPopulation(player: Player): number { + let maxPop = Math.sqrt(player.numTilesOwned()) * 3000 + 50000 if (player.type() == PlayerType.Bot) { - return manpower + return maxPop } - return manpower * 2 + return maxPop * 2 } - manpowerAdditionRate(player: Player): number { - let max = this.maxManpower(player) + populationIncreaseRate(player: Player): number { + let max = this.maxPopulation(player) - let toAdd = 10 + (player.totalManpower() + Math.sqrt(player.totalManpower() * player.numTilesOwned())) / 100 + let toAdd = 10 + (player.population() + Math.sqrt(player.population() * player.numTilesOwned())) / 100 - const ratio = 1 - (player.totalManpower() / max) + const ratio = 1 - (player.population() / max) toAdd *= ratio toAdd *= .5 // console.log(`to add ${toAdd}`) @@ -155,14 +154,17 @@ export class DefaultConfig implements Config { if (player.type() == PlayerType.Bot) { toAdd *= .7 } - return toAdd + + return Math.min(player.troops() + toAdd, max) - player.troops() } + goldAdditionRate(player: Player): number { - return (player.manpowerReserve() * 1.2 - player.troops()) / 1000 + return Math.sqrt(player.workers() * player.numTilesOwned()) / 1000 + player.gold() * .001 } + troopAdjustmentRate(player: Player): number { - const maxDiff = player.maxTroops() / 300 - const target = player.maxTroops() * player.targetTroopRatio() + const maxDiff = this.maxPopulation(player) / 300 + const target = player.population() * player.targetTroopRatio() const diff = target - player.troops() if (Math.abs(diff) < maxDiff) { return diff diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts index e1ecb147c..44cc61094 100644 --- a/src/core/execution/ExecutionManager.ts +++ b/src/core/execution/ExecutionManager.ts @@ -15,6 +15,7 @@ import { TargetPlayerExecution } from "./TargetPlayerExecution"; import { EmojiExecution } from "./EmojiExecution"; import { DonateExecution } from "./DonateExecution"; import { NukeExecution } from "./NukeExecution"; +import { SetTargetTroopRatioExecution } from "./SetTargetTroopRatioExecution"; diff --git a/src/core/execution/FakeHumanExecution.ts b/src/core/execution/FakeHumanExecution.ts index 49fbd4e81..33be8a15e 100644 --- a/src/core/execution/FakeHumanExecution.ts +++ b/src/core/execution/FakeHumanExecution.ts @@ -64,7 +64,7 @@ export class FakeHumanExecution implements Execution { return } - if (this.player.troops() < this.mg.config().maxManpower(this.player) / 4) { + if (this.player.troops() < this.mg.config().maxPopulation(this.player) / 4) { return } diff --git a/src/core/execution/PlayerExecution.ts b/src/core/execution/PlayerExecution.ts index 641cd2b75..c667f9e26 100644 --- a/src/core/execution/PlayerExecution.ts +++ b/src/core/execution/PlayerExecution.ts @@ -30,13 +30,14 @@ export class PlayerExecution implements Execution { if (ticks < this.config.numSpawnPhaseTurns()) { return } + const popInc = this.config.populationIncreaseRate(this.player) - this.player.addManpowerReserve(this.config.manpowerAdditionRate(this.player)) - this.player.setMaxTroops(Math.max(this.player.numTilesOwned() * 100, 50000)) + this.player.addWorkers(popInc * (1 - this.player.targetTroopRatio()))// (1 - this.player.targetTroopRatio())) + this.player.addTroops(popInc * this.player.targetTroopRatio()) this.player.addGold(this.config.goldAdditionRate(this.player)) const adjustRate = this.config.troopAdjustmentRate(this.player) this.player.addTroops(adjustRate) - this.player.removeManpowerReserve(adjustRate) + this.player.removeWorkers(adjustRate) const alliances = Array.from(this.player.alliances()) for (const alliance of alliances) { diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 6e2f1c783..47b7759e1 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -167,7 +167,6 @@ export interface Player { clientID(): ClientID id(): PlayerID type(): PlayerType - troops(): number boats(): Boat[] ownsTile(cell: Cell): boolean isAlive(): boolean @@ -196,17 +195,15 @@ export interface Player { outgoingEmojis(): EmojiMessage[] canDonate(recipient: Player): boolean gold(): Gold - totalManpower(): number - manpowerReserve(): number + // Population = troops + workers + population(): number + workers(): number // Number between 0, 1 targetTroopRatio(): number - maxTroops(): number + troops(): number } export interface MutablePlayer extends Player { - setTroops(troops: number): void - addTroops(troops: number): void - removeTroops(troops: number): number conquer(tile: Tile): void relinquish(tile: Tile): void executions(): Execution[] @@ -224,12 +221,16 @@ export interface MutablePlayer extends Player { transitiveTargets(): MutablePlayer[] sendEmoji(recipient: Player | typeof AllPlayers, emoji: string): void donate(recipient: MutablePlayer, troops: number): void + addGold(toAdd: Gold): void removeGold(toRemove: Gold): void - addManpowerReserve(toAdd: number): void - removeManpowerReserve(toRemove: number): void + + addWorkers(toAdd: number): void + removeWorkers(toRemove: number): void setTargetTroopRatio(target: number): void - setMaxTroops(maxTroops: number): void + setTroops(troops: number): void + addTroops(troops: number): void + removeTroops(troops: number): number } export interface Game { diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index c7f02e56e..eb3b0b03c 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -1,4 +1,4 @@ -import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, TargetPlayerEvent, EmojiMessage, EmojiMessageEvent, AllPlayers, Currency } from "./Game"; +import { MutablePlayer, Tile, PlayerInfo, PlayerID, PlayerType, Player, TerraNullius, Cell, Execution, AllianceRequest, MutableAllianceRequest, MutableAlliance, Alliance, Tick, TargetPlayerEvent, EmojiMessage, EmojiMessageEvent, AllPlayers, Gold } from "./Game"; import { ClientID } from "../Schemas"; import { processName, simpleHash } from "../Util"; import { CellString, GameImpl } from "./GameImpl"; @@ -22,9 +22,8 @@ export class PlayerImpl implements MutablePlayer { private _gold: Gold private _troops: number - private _reserves: number - private _targetTroopRatio: number - private _maxTroops: number + private _workers: number + private _targetTroopRatio: number = 1 isTraitor_ = false @@ -34,7 +33,7 @@ export class PlayerImpl implements MutablePlayer { public _tiles: Map = new Map(); private _name: string; - private _displayerName: string; + private _displayName: string; public pastOutgoingAllianceRequests: AllianceRequest[] = [] @@ -44,20 +43,21 @@ export class PlayerImpl implements MutablePlayer { private sentDonations: Donation[] = [] - constructor(private gs: GameImpl, private readonly playerInfo: PlayerInfo, manpower: number) { + constructor(private gs: GameImpl, private readonly playerInfo: PlayerInfo, startPopulation: number) { this._name = playerInfo.name; - this._targetTroopRatio = .5 - this._troops = manpower * this._targetTroopRatio; - this._reserves = manpower * (1 - this._targetTroopRatio) + this._targetTroopRatio = 1 + this._troops = startPopulation * this._targetTroopRatio; + this._workers = startPopulation * (1 - this._targetTroopRatio) this._gold = 0 - this._maxTroops = 0 + this._displayName = processName(this._name) + } name(): string { return this._name; } displayName(): string { - return this._displayerName + return this._displayName } clientID(): ClientID { @@ -118,22 +118,6 @@ export class PlayerImpl implements MutablePlayer { return Array.from(ns); } - addTroops(troops: number): void { - if (troops < 0) { - this.removeTroops(-1 * troops) - return - } - this._troops += Math.floor(troops); - } - removeTroops(troops: number): number { - if (troops <= 1) { - return 0 - } - const toRemove = Math.floor(Math.min(this._troops - 1, troops)) - this._troops -= toRemove; - return toRemove - } - isPlayer(): this is MutablePlayer { return true as const; } ownsTile(cell: Cell): boolean { return this._tiles.has(cell.toString()); } setTroops(troops: number) { this._troops = Math.floor(troops); } @@ -145,7 +129,6 @@ export class PlayerImpl implements MutablePlayer { this.gs.relinquish(tile); } info(): PlayerInfo { return this.playerInfo; } - troops(): number { return this._troops; } isAlive(): boolean { return this._tiles.size > 0; } executions(): Execution[] { return this.gs.executions().filter(exec => exec.owner().id() == this.id()); @@ -297,17 +280,17 @@ export class PlayerImpl implements MutablePlayer { this._gold -= toRemove } - totalManpower(): number { - return this._troops + this._reserves + population(): number { + return this._troops + this._workers } - manpowerReserve(): number { - return Math.max(1, this._reserves) + workers(): number { + return Math.max(1, this._workers) } - addManpowerReserve(toAdd: number): void { - this._reserves += toAdd + addWorkers(toAdd: number): void { + this._workers += toAdd } - removeManpowerReserve(toRemove: number): void { - this._reserves = Math.max(1, this._reserves - toRemove) + removeWorkers(toRemove: number): void { + this._workers = Math.max(1, this._workers - toRemove) } targetTroopRatio(): number { @@ -321,15 +304,27 @@ export class PlayerImpl implements MutablePlayer { this._targetTroopRatio = target } - maxTroops(): number { - return this._maxTroops + troops(): number { return this._troops; } + + addTroops(troops: number): void { + if (troops < 0) { + this.removeTroops(-1 * troops) + return + } + this._troops += Math.floor(troops); } - setMaxTroops(maxTroops: number): void { - this._maxTroops = maxTroops + removeTroops(troops: number): number { + if (troops <= 1) { + return 0 + } + const toRemove = Math.floor(Math.min(this._troops - 1, troops)) + this._troops -= toRemove; + return toRemove } + hash(): number { - return simpleHash(this.id()) * (this.totalManpower() + this.numTilesOwned()); + return simpleHash(this.id()) * (this.population() + this.numTilesOwned()); } toString(): string { return `Player:{name:${this.info().name},clientID:${this.info().clientID},isAlive:${this.isAlive()},troops:${this._troops},numTileOwned:${this.numTilesOwned()}}]`;