import {Config} from "./configuration/Config" import {GameEvent} from "./EventBus" import {ClientID, GameID} from "./Schemas" export type PlayerID = string export class Cell { private strRepr: string constructor( public readonly x, public readonly y ) { this.strRepr = `Cell[${this.x},${this.y}]` } toString(): string {return this.strRepr} } export interface ExecutionView { isActive(): boolean owner(): Player activeDuringSpawnPhase(): boolean } export interface Execution extends ExecutionView { init(mg: MutableGame, ticks: number): void tick(ticks: number): void owner(): MutablePlayer } export class PlayerInfo { constructor( public readonly name: string, public readonly isBot: boolean, // null if bot. public readonly clientID: ClientID | null, public readonly id: PlayerID ) { } } export interface Tile { isLand(): boolean isShore(): boolean isOceanShore(): boolean isWater(): boolean isShorelineWater(): boolean isOcean(): boolean isLake(): boolean magnitude(): number owner(): Player | TerraNullius hasOwner(): boolean isBorder(): boolean borders(other: Player | TerraNullius): boolean isInterior(): boolean cell(): Cell game(): Game neighbors(): Tile[] neighborsWrapped(): Tile[] onShore(): boolean } export interface Boat { troops(): number tile(): Tile owner(): Player target(): Player | TerraNullius isActive(): boolean } export interface MutableBoat extends Boat { move(tile: Tile): void owner(): MutablePlayer target(): MutablePlayer | TerraNullius setTroops(troops: number): void delete(): void } export interface TerraNullius { ownsTile(cell: Cell): boolean isPlayer(): false id(): PlayerID // always zero, maybe make it TerraNulliusID? } export interface Player { name(): string clientID(): ClientID id(): PlayerID isBot(): boolean troops(): number boats(): Boat[] ownsTile(cell: Cell): boolean isAlive(): boolean executions(): ExecutionView[] borderTiles(): ReadonlySet isPlayer(): this is Player neighbors(): (Player | TerraNullius)[] numTilesOwned(): number tiles(): ReadonlySet sharesBorderWith(other: Player | TerraNullius): boolean toString(): string } export interface MutablePlayer extends Player { setName(name: string): void setTroops(troops: number): void addTroops(troops: number): void removeTroops(troops: number): void conquer(tile: Tile): void relinquish(tile: Tile): void executions(): Execution[] neighbors(): (MutablePlayer | TerraNullius)[] boats(): MutableBoat[] addBoat(troops: number, tile: Tile, target: Player | TerraNullius): MutableBoat } export interface Game { // Throws exception is player not found player(id: PlayerID): Player hasPlayer(id: PlayerID): boolean players(): Player[] tile(cell: Cell): Tile isOnMap(cell: Cell): boolean neighbors(cell: Cell | Tile): Tile[] width(): number height(): number forEachTile(fn: (tile: Tile) => void): void executions(): ExecutionView[] terraNullius(): TerraNullius tick(): void ticks(): number inSpawnPhase(): boolean addExecution(...exec: Execution[]): void config(): Config } export interface MutableGame extends Game { player(id: PlayerID): MutablePlayer players(): MutablePlayer[] addPlayer(playerInfo: PlayerInfo, troops: number): MutablePlayer executions(): Execution[] removeInactiveExecutions(): void removeExecution(exec: Execution) } export class TileEvent implements GameEvent { constructor(public readonly tile: Tile) { } } export class PlayerEvent implements GameEvent { constructor(public readonly player: Player) { } } export class BoatEvent implements GameEvent { constructor(public readonly boat: Boat, public oldTile: Tile) { } }