From 5f5f8ddf641a49bd3439583733e972fa747b6f72 Mon Sep 17 00:00:00 2001 From: Evan Date: Fri, 24 Jan 2025 10:25:47 -0800 Subject: [PATCH] move methods from GameRunner to PlayerImpl --- src/core/GameRunner.ts | 98 +++---------------------------------- src/core/game/Game.ts | 3 ++ src/core/game/PlayerImpl.ts | 91 ++++++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 95 deletions(-) diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts index 9d04ff48a..85e9004d8 100644 --- a/src/core/GameRunner.ts +++ b/src/core/GameRunner.ts @@ -110,8 +110,8 @@ export class GameRunner { const player = this.game.player(playerID) const tile = this.game.ref(x, y) const actions = { - canBoat: this.canBoat(player, tile), - canAttack: this.canAttack(player, tile), + canBoat: player.canBoat(tile), + canAttack: player.canAttack(tile), buildableUnits: Object.values(UnitType).filter(ut => player.canBuild(ut, tile) != false), canSendEmojiAllPlayers: player.canSendEmoji(AllPlayers) } as PlayerActions @@ -130,97 +130,11 @@ export class GameRunner { return actions } - - public playerProfile(playerID: number): PlayerProfile { - const player = this.game.players().filter(p => p.smallID() == playerID)[0]; - if (!player) { - throw new Error(`player with id ${playerID} not found`); - } - - const rel = { - relations: Object.fromEntries( - player.allRelationsSorted() - .map(({ player, relation }) => [player.smallID(), relation]) - ), - alliances: player.alliances().map(a => a.other(player).smallID()) - }; - return rel - } - - private canBoat(myPlayer: Player, tile: TileRef): boolean { - const other = this.game.owner(tile) - if (myPlayer.units(UnitType.TransportShip).length >= this.game.config().boatMaxNumber()) { - return false - } - - let myPlayerBordersOcean = false - for (const bt of myPlayer.borderTiles()) { - if (this.game.isOceanShore(bt)) { - myPlayerBordersOcean = true - break - } - } - let otherPlayerBordersOcean = false - if (!this.game.hasOwner(tile)) { - otherPlayerBordersOcean = true - } else { - for (const bt of (other as Player).borderTiles()) { - if (this.game.isOceanShore(bt)) { - otherPlayerBordersOcean = true - break - } - } - } - - if (other.isPlayer() && myPlayer.allianceWith(other)) { - return false - } - - let nearOcean = false - for (const t of this.game.bfs(tile, andFN((gm, t) => gm.ownerID(t) == gm.ownerID(tile) && gm.isLand(t), manhattanDistFN(tile, 25)))) { - if (this.game.isOceanShore(t)) { - nearOcean = true - break - } - } - if (!nearOcean) { - return false - } - - if (myPlayerBordersOcean && otherPlayerBordersOcean) { - const dst = targetTransportTile(this.game, tile) - if (dst != null) { - if (myPlayer.canBuild(UnitType.TransportShip, dst)) { - return true - } - } - } - } - - private canAttack(myPlayer: Player, tile: TileRef): boolean { - if (this.game.owner(tile) == myPlayer) { - return false - } - // TODO: fix event bus - if (this.game.hasOwner(tile) && myPlayer.isAlliedWith(this.game.owner(tile) as Player)) { - // this.eventBus.emit(new DisplayMessageEvent("Cannot attack ally", MessageType.WARN)) - return false - } - if (!this.game.isLand(tile)) { - return false - } - if (this.game.hasOwner(tile)) { - return myPlayer.sharesBorderWith(this.game.owner(tile)) - } else { - for (const t of this.game.bfs(tile, andFN((gm, t) => !gm.hasOwner(t) && gm.isLand(t), manhattanDistFN(tile, 200)))) { - for (const n of this.game.neighbors(t)) { - if (this.game.owner(n) == myPlayer) { - return true - } - } - } - return false + const player = this.game.playerBySmallID(playerID) + if (!player.isPlayer()) { + throw new Error(`player with id ${playerID} not found`) } + return player.playerProfile() } } diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index e50feb061..4d4a2cfb2 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -283,6 +283,9 @@ export interface Player { // Misc executions(): Execution[] toUpdate(): PlayerUpdate + playerProfile(): PlayerProfile + canBoat(tile: TileRef): boolean + canAttack(tile: TileRef) } export interface Game extends GameMap { diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index 345964cbc..f00d8d91a 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -1,14 +1,14 @@ -import { Player, PlayerInfo, PlayerID, PlayerType, TerraNullius, Cell, Execution, AllianceRequest, MutableAlliance, Alliance, Tick, AllPlayers, Gold, UnitType, Unit, Relation, EmojiMessage } from "./Game"; +import { Player, PlayerInfo, PlayerID, PlayerType, TerraNullius, Cell, Execution, AllianceRequest, MutableAlliance, Alliance, Tick, AllPlayers, Gold, UnitType, Unit, Relation, EmojiMessage, PlayerProfile } from "./Game"; import { PlayerUpdate } from "./GameUpdates"; import { GameUpdateType } from "./GameUpdates"; import { ClientID } from "../Schemas"; -import { assertNever, closestOceanShoreFromPlayer, distSortUnit, simpleHash, sourceDstOceanShore, within } from "../Util"; +import { assertNever, closestOceanShoreFromPlayer, distSortUnit, simpleHash, sourceDstOceanShore, targetTransportTile, within } from "../Util"; import { CellString, GameImpl } from "./GameImpl"; import { UnitImpl } from "./UnitImpl"; import { MessageType } from './Game'; import { renderTroops } from "../../client/Utils"; import { TerraNulliusImpl } from "./TerraNulliusImpl"; -import { manhattanDistFN, TileRef } from "./GameMap"; +import { andFN, manhattanDistFN, TileRef } from "./GameMap"; import { Emoji } from "discord.js"; interface Target { @@ -548,4 +548,89 @@ export class PlayerImpl implements Player { toString(): string { return `Player:{name:${this.info().name},clientID:${this.info().clientID},isAlive:${this.isAlive()},troops:${this._troops},numTileOwned:${this.numTilesOwned()}}]`; } + + public playerProfile(): PlayerProfile { + const rel = { + relations: Object.fromEntries( + this.allRelationsSorted() + .map(({ player, relation }) => [player.smallID(), relation]) + ), + alliances: this.alliances().map(a => a.other(this).smallID()) + }; + return rel + } + + public canBoat(tile: TileRef): boolean { + const other = this.mg.owner(tile) + if (this.units(UnitType.TransportShip).length >= this.mg.config().boatMaxNumber()) { + return false + } + + let myPlayerBordersOcean = false + for (const bt of this.borderTiles()) { + if (this.mg.isOceanShore(bt)) { + myPlayerBordersOcean = true + break + } + } + let otherPlayerBordersOcean = false + if (!this.mg.hasOwner(tile)) { + otherPlayerBordersOcean = true + } else { + for (const bt of (other as Player).borderTiles()) { + if (this.mg.isOceanShore(bt)) { + otherPlayerBordersOcean = true + break + } + } + } + + if (other.isPlayer() && this.allianceWith(other)) { + return false + } + + let nearOcean = false + for (const t of this.mg.bfs(tile, andFN((gm, t) => gm.ownerID(t) == gm.ownerID(tile) && gm.isLand(t), manhattanDistFN(tile, 25)))) { + if (this.mg.isOceanShore(t)) { + nearOcean = true + break + } + } + if (!nearOcean) { + return false + } + + if (myPlayerBordersOcean && otherPlayerBordersOcean) { + const dst = targetTransportTile(this.mg, tile) + if (dst != null) { + if (this.canBuild(UnitType.TransportShip, dst)) { + return true + } + } + } + } + + public canAttack(tile: TileRef): boolean { + if (this.mg.owner(tile) == this) { + return false + } + if (this.mg.hasOwner(tile) && this.isAlliedWith(this.mg.owner(tile) as Player)) { + return false + } + if (!this.mg.isLand(tile)) { + return false + } + if (this.mg.hasOwner(tile)) { + return this.sharesBorderWith(this.mg.owner(tile)) + } else { + for (const t of this.mg.bfs(tile, andFN((gm, t) => !gm.hasOwner(t) && gm.isLand(t), manhattanDistFN(tile, 200)))) { + for (const n of this.mg.neighbors(t)) { + if (this.mg.owner(n) == this) { + return true + } + } + } + return false + } + } }