diff --git a/src/ps/games/scrabble/constants.ts b/src/ps/games/scrabble/constants.ts index 364282d..3a2fb59 100644 --- a/src/ps/games/scrabble/constants.ts +++ b/src/ps/games/scrabble/constants.ts @@ -120,4 +120,5 @@ export enum ScrabbleMods { CLABBERS = 'clabbers', POKEMON = 'pokemon', CRAZYMONS = 'crazymons', + SUPER = 'super', } diff --git a/src/ps/games/scrabble/index.ts b/src/ps/games/scrabble/index.ts index d5b73a1..7263cd7 100644 --- a/src/ps/games/scrabble/index.ts +++ b/src/ps/games/scrabble/index.ts @@ -70,8 +70,8 @@ export class Scrabble extends BaseGame { if (!applyMons.success) throw new Error(applyMons.error); this.room.send(this.$T('GAME.SCRABBLE.AUTO_MOD_APPLIED', { id: this.id, mod: ScrabbleModData[defaultMod].name })); } - this.state.baseBoard = BaseBoard; - this.state.board = createGrid(BaseBoard.length, BaseBoard[0].length, () => null); + this.state.baseBoard = (this.mod ? ScrabbleModData[this.mod].board : null) ?? BaseBoard; + this.state.board = createGrid(this.state.baseBoard.length, this.state.baseBoard[0].length, () => null); this.state.bag = Object.entries((this.mod ? ScrabbleModData[this.mod].counts : null) ?? LETTER_COUNTS) .flatMap(([letter, count]) => letter.repeat(count).split('')) .shuffle(this.prng); diff --git a/src/ps/games/scrabble/mods.ts b/src/ps/games/scrabble/mods.ts index 6745ecf..c7c69b4 100644 --- a/src/ps/games/scrabble/mods.ts +++ b/src/ps/games/scrabble/mods.ts @@ -1,11 +1,11 @@ import { DICTIONARY, ScrabbleMods } from '@/ps/games/scrabble/constants'; import type { BaseModEntry } from '@/ps/games/mods'; -import type { LetterMetadata, WordScore } from '@/ps/games/scrabble/types'; +import type { BaseBoard as BaseBoardType, LetterMetadata, WordScore } from '@/ps/games/scrabble/types'; export const ScrabbleModData: Record< ScrabbleMods, - BaseModEntry & { dict: DICTIONARY; points?: LetterMetadata; counts?: LetterMetadata } + BaseModEntry & { dict: DICTIONARY; points?: LetterMetadata; counts?: LetterMetadata; board?: BaseBoardType } > = { [ScrabbleMods.CSW19]: { id: ScrabbleMods.CSW19, @@ -111,6 +111,65 @@ export const ScrabbleModData: Record< dict: DICTIONARY.CSW24, aliases: ['crazy'], }, + [ScrabbleMods.SUPER]: { + id: ScrabbleMods.SUPER, + name: 'Super Scrabble', + desc: 'Super Scrabble, with a super board! See https://en.wikipedia.org/wiki/Super_Scrabble', + dict: DICTIONARY.CSW24, + counts: { + A: 16, + B: 4, + C: 6, + D: 8, + E: 24, + F: 4, + G: 5, + H: 5, + I: 13, + J: 2, + K: 2, + L: 7, + M: 6, + N: 13, + O: 15, + P: 4, + Q: 2, + R: 13, + S: 10, + T: 15, + U: 7, + V: 3, + W: 4, + X: 2, + Y: 4, + Z: 2, + _: 4, + }, + board: [ + ['4W', null, null, '2L', null, null, null, '3W', null, null, '2L', null, null, '3W', null, null, null, '2L', null, null, '4W'], + [null, '2W', null, null, '3L', null, null, null, '2W', null, null, null, '2W', null, null, null, '3L', null, null, '2W', null], + [null, null, '2W', null, null, '4L', null, null, null, '2W', null, '2W', null, null, null, '4L', null, null, '2W', null, null], + ['2L', null, null, '3W', null, null, '2L', null, null, null, '3W', null, null, null, '2L', null, null, '3W', null, null, '2L'], + [null, '3L', null, null, '2W', null, null, null, '3L', null, null, null, '3L', null, null, null, '2W', null, null, '3L', null], + [null, null, '4L', null, null, '2W', null, null, null, '2L', null, '2L', null, null, null, '2W', null, null, '4L', null, null], + [null, null, null, '2L', null, null, '2W', null, null, null, '2L', null, null, null, '2W', null, null, '2L', null, null, null], + ['3W', null, null, null, null, null, null, '2W', null, null, null, null, null, '2W', null, null, null, null, null, null, '3W'], + [null, '2W', null, null, '3L', null, null, null, '3L', null, null, null, '3L', null, null, null, '3L', null, null, '2W', null], + [null, null, '2W', null, null, '2L', null, null, null, '2L', null, '2L', null, null, null, '2L', null, null, '2W', null, null], + ['2L', null, null, '3W', null, null, '2L', null, null, null, '2*', null, null, null, '2L', null, null, '3W', null, null, '2L'], + [null, null, '2W', null, null, '2L', null, null, null, '2L', null, '2L', null, null, null, '2L', null, null, '2W', null, null], + [null, '2W', null, null, '3L', null, null, null, '3L', null, null, null, '3L', null, null, null, '3L', null, null, '2W', null], + ['3W', null, null, null, null, null, null, '2W', null, null, null, null, null, '2W', null, null, null, null, null, null, '3W'], + [null, null, null, '2L', null, null, '2W', null, null, null, '2L', null, null, null, '2W', null, null, '2L', null, null, null], + [null, null, '4L', null, null, '2W', null, null, null, '2L', null, '2L', null, null, null, '2W', null, null, '4L', null, null], + [null, '3L', null, null, '2W', null, null, null, '3L', null, null, null, '3L', null, null, null, '2W', null, null, '3L', null], + ['2L', null, null, '3W', null, null, '2L', null, null, null, '3W', null, null, null, '2L', null, null, '3W', null, null, '2L'], + [null, null, '2W', null, null, '4L', null, null, null, '2W', null, '2W', null, null, null, '4L', null, null, '2W', null, null], + [null, '2W', null, null, '3L', null, null, null, '2W', null, null, null, '2W', null, null, null, '3L', null, null, '2W', null], + ['4W', null, null, '2L', null, null, null, '3W', null, null, '2L', null, null, '3W', null, null, null, '2L', null, null, '4W'], + ], + aliases: ['superscrabble'], + }, }; export const POKEMON_SCORING: WordScore = [2, 10]; diff --git a/src/ps/games/scrabble/render.tsx b/src/ps/games/scrabble/render.tsx index a3c9c35..48ce7d0 100644 --- a/src/ps/games/scrabble/render.tsx +++ b/src/ps/games/scrabble/render.tsx @@ -27,8 +27,7 @@ export function renderMove(logEntry: Log, game: Scrabble): [ReactElement, { name {words.length === 1 && !logEntry.ctx.points.bingo ? words[0][0] : words.map(([word, points]) => `${word} (${points})`).list(game.$T)}{' '} - for {pluralize(logEntry.ctx.points.total, 'point', 'points')}! - {logEntry.ctx.points.bingo ? ' BINGO!' : null} + for {pluralize(logEntry.ctx.points.total, 'point', 'points')}!{logEntry.ctx.points.bingo ? ' BINGO!' : null} , opts, ]; @@ -79,6 +78,10 @@ function getBackgroundHex(bonus: Bonus | null): string { return '#e65'; case '3L': return '#49a'; + case '4W': + return '#a12'; + case '4L': + return '#14a'; default: return '#cca'; } diff --git a/src/ps/games/scrabble/types.ts b/src/ps/games/scrabble/types.ts index 7cece13..d5a118a 100644 --- a/src/ps/games/scrabble/types.ts +++ b/src/ps/games/scrabble/types.ts @@ -11,7 +11,7 @@ export type BoardTile = { type Letter = 'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'|'_'; export type LetterMetadata = Record; -export type Bonus = '3W' | '2W' | '3L' | '2L' | '2*'; +export type Bonus = '4W' | '3W' | '2W' | '4L' | '3L' | '2L' | '2*'; export type BonusReducer = { apply: (score: number) => number; weight: number }; export type BaseBoard = (Bonus | null)[][];