thomaswilson-sveltekit/src/lib/floriferous/floriferous-game.ts

85 lines
2.1 KiB
TypeScript

import type { FloriferousPlayer } from './floriferous-player.js';
import { intlFormat as formatDate } from 'date-fns';
import { nanoid } from 'nanoid';
export interface FloriferousGameParams {
playedTs?: Date;
id?: string;
players?: FloriferousPlayer[];
}
export class FloriferousGame {
readonly id: string;
readonly playedTs: Date;
private _players: FloriferousPlayer[] = [];
constructor({ id = nanoid(), playedTs = new Date(), players = [] }: FloriferousGameParams = {}) {
this.id = id;
this.playedTs = playedTs;
this._players = players;
}
addPlayer(player: FloriferousPlayer): void {
this._players.push(player);
}
addPlayers(players: FloriferousPlayer[]): void {
players.forEach((player) => {
this.addPlayer(player);
});
}
get prettySummary(): string {
if (this._players.length === 0) {
return '';
}
const formattedDate = formatDate(this.playedTs, {
localeMatcher: 'best fit',
weekday: 'long',
day: 'numeric',
month: 'long',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
const winnerStatement = `${this.winningPlayer.name} won with ${this.winningPlayer.score} points`;
const otherPlayerStatements = this.nonWinningsPlayers.map((player) => {
return `${player.name}: ${player.score} point${player.score === 1 ? '' : 's'}.`;
});
return [`${formattedDate}: ${winnerStatement}`, ...otherPlayerStatements].join('. ');
}
get players(): FloriferousPlayer[] {
return this._players;
}
private get winningPlayer(): FloriferousPlayer | undefined {
if (this._players.length === 0) {
return undefined;
}
const playersSortedByScore = this._players.sort((a, b) => {
return b.score - a.score;
});
if (playersSortedByScore[0].score === playersSortedByScore[1].score) {
const playersSortedByRowAtEndOfGame = this._players.sort((a, b) => {
return a.rowAtEndOfGame - b.rowAtEndOfGame;
});
return playersSortedByRowAtEndOfGame[0];
}
return playersSortedByScore[0];
}
private get nonWinningsPlayers(): FloriferousPlayer[] {
return this._players.filter((player) => player.name !== this.winner);
}
get winner(): string | undefined {
return this.winningPlayer?.name;
}
}