import { Board } from "../Board"; import { PlayerInterface } from "./PlayerInterface"; import { PlayerMove } from "../PlayerMove"; import { Tile } from "../Tile"; import { LoggingService } from "../../../common/LoggingService"; import { EventEmitter } from "stream"; import { PlayerInteractionInterface } from "../../PlayerInteractionInterface"; import { uuid } from "../../../common/utilities"; import { GameState } from "../../dto/GameState"; import { MatchSessionState } from "../../dto/MatchSessionState"; import { PlayerDto } from "../../dto/PlayerDto"; export abstract class AbstractPlayer extends EventEmitter implements PlayerInterface { hand: Tile[] = []; score: number = 0; logger: LoggingService = new LoggingService(); teamedWith: PlayerInterface | null = null; playerInteraction: PlayerInteractionInterface = undefined as any; id: string = uuid(); ready: boolean = false; constructor(public name: string) { super(); } abstract makeMove(board: Board): Promise; abstract chooseTile(board: Board): Promise; async notifyGameState(state: GameState): Promise { } async notifyPlayerState(state: PlayerDto): Promise { } async notifyMatchState(state: MatchSessionState): Promise { } async waitForAction(actionId: string): Promise { return true; } async sendEvent(event: string): Promise { } pipsCount(): number { return this.hand.reduce((acc, tile) => acc + tile.pips[0] + tile.pips[1], 0); } getHighestPair(): Tile | null { if (this.hand.length === 0) { return null; } let highestPair: Tile | null = null; const pairs = this.hand.filter(tile => tile.pips[0] === tile.pips[1]); pairs.forEach(tile => { if (tile.count > (highestPair?.count ?? 0)) { highestPair = tile; } }); return highestPair; } getState(showPips: boolean = false): PlayerDto { return { id: this.id, name: this.name, score: this.score, hand: this.hand.map(tile => { const d = { id: tile.id, pips: tile.pips, flipped: tile.revealed, }; if (showPips) { d.pips = tile.pips; } return d; }), teamedWith: this.teamedWith?.getState() ?? null, ready: this.ready, }; } }