scrabble-solver
Version:
Scrabble Solver 2 - Free, open-source, cross-platform, multi-language analysis tool for Scrabble, Scrabble Duel, Super Scrabble, Letter League, Crossplay, Literaki, and Kelimelik. Quickly find the top-scoring words using the given board and tiles.
82 lines (63 loc) • 2.51 kB
text/typescript
import { BLANK, CONSONANTS, VOWELS } from '@scrabble-solver/constants';
import { type RemainingTile, type RemainingTilesGroup } from '@/types';
export const getRemainingTilesGroups = (remainingTiles: RemainingTile[]): RemainingTilesGroup[] => {
const consonants = remainingTiles.filter(isConsonant);
const vowels = remainingTiles.filter(isVowel);
const other = remainingTiles.filter(isOther);
const groups: RemainingTilesGroup[] = [];
groups.push({
remainingCount: getRemainingTilesCount(vowels),
tiles: vowels,
translationKey: 'common.vowels',
totalCount: getTotalTilesCount(vowels),
});
groups.push({
remainingCount: getRemainingTilesCount(consonants),
tiles: consonants,
translationKey: 'common.consonants',
totalCount: getTotalTilesCount(consonants),
});
groups.push({
remainingCount: getRemainingTilesCount(other),
tiles: other,
translationKey: 'common.tiles',
totalCount: getTotalTilesCount(other),
});
const twoCharacterTiles = remainingTiles.filter(isTwoCharacter);
const blanks = remainingTiles.filter(isBlank);
groups.push({
remainingCount: getRemainingTilesCount(twoCharacterTiles),
tiles: twoCharacterTiles,
translationKey: 'common.two-letter-tiles',
totalCount: getTotalTilesCount(twoCharacterTiles),
});
groups.push({
remainingCount: getRemainingTilesCount(blanks),
tiles: blanks,
translationKey: 'common.blanks',
totalCount: getTotalTilesCount(blanks),
});
return groups.filter(({ totalCount }) => totalCount > 0);
};
const isConsonant = (tile: RemainingTile): boolean => CONSONANTS.includes(tile.character);
const isVowel = (tile: RemainingTile): boolean => VOWELS.includes(tile.character);
const isTwoCharacter = (tile: RemainingTile): boolean => tile.character.length === 2;
const isBlank = (tile: RemainingTile): boolean => tile.character === BLANK;
const isOther = (tile: RemainingTile) =>
!isConsonant(tile) && !isVowel(tile) && !isBlank(tile) && !isTwoCharacter(tile);
const getRemainingTilesCount = (remainingTiles: RemainingTile[]): number => {
return remainingTiles.reduce((sum, { count, usedCount }) => {
if (typeof count === 'undefined') {
return sum;
}
return sum + count - usedCount;
}, 0);
};
const getTotalTilesCount = (remainingTiles: RemainingTile[]): number => {
return remainingTiles.reduce((sum, { count }) => {
if (typeof count === 'undefined') {
return sum;
}
return sum + count;
}, 0);
};