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.
108 lines (91 loc) • 3.88 kB
text/typescript
import { type Trie } from '@kamilmielnik/trie';
import { getConfig } from '@scrabble-solver/configs';
import { dictionaries } from '@scrabble-solver/dictionaries';
import { Board, Cell, FinalPattern, Game, Locale, type Pattern, Tile, VerticalPattern } from '@scrabble-solver/types';
import { fillPattern, fillPatternRecursive } from './fillPattern';
const board = Board.fromStringArray([' t ', 'do ', ' ']);
const locale = Locale.PL_PL;
const config = getConfig(Game.Literaki, locale);
describe('fillPattern', () => {
let trie: Trie | undefined;
beforeAll(() => {
return dictionaries.get(locale).then((loadedTrie) => {
trie = loadedTrie;
});
});
it('fills patterns', () => {
const pattern = new VerticalPattern(board, [
new Cell({ x: 0, y: 0 }),
new Cell({ x: 0, y: 1, tile: new Tile({ character: 'd', isBlank: false }) }),
new Cell({ x: 0, y: 2 }),
]);
const tiles = [
new Tile({ character: 'o', isBlank: false }),
new Tile({ character: 'a', isBlank: false }),
new Tile({ character: 'd', isBlank: false }),
];
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
expect(filledPatterns.length).toBe(1);
});
it('fills patterns with blanks', () => {
const pattern = new VerticalPattern(board, [board.rows[0][1], board.rows[1][1], board.rows[2][1]]);
const tiles = [new Tile({ character: ' ', isBlank: true }), new Tile({ character: 'ó', isBlank: false })];
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
expect(filledPatterns.map(String)).toEqual([
'toć',
'tog',
'toi',
'tok',
'tom',
'ton',
'toń',
'top',
'tor',
'tos',
'toy',
'toż',
]);
});
it('does not modify filled patterns', () => {
const pattern = new FinalPattern(
new VerticalPattern(board, [
new Cell({ x: 0, y: 0, isEmpty: false, tile: new Tile({ character: 'o', isBlank: false }) }),
new Cell({ x: 0, y: 1, isEmpty: false, tile: new Tile({ character: 'k', isBlank: false }) }),
new Cell({ x: 0, y: 2, isEmpty: false, tile: new Tile({ character: 'o', isBlank: false }) }),
]),
);
const tiles = [new Tile({ character: 'ń', isBlank: false })];
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
expect(filledPatterns.length).toBe(1);
expect(filledPatterns[0]).toEqual(pattern);
});
it('does not accept non-placeable filled patterns', () => {
const pattern = new VerticalPattern(board, [
new Cell({ x: 0, y: 0, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
new Cell({ x: 0, y: 1, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
new Cell({ x: 0, y: 2, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
]);
const tiles = [new Tile({ character: 'ń', isBlank: false })];
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
expect(filledPatterns.length).toBe(0);
});
});
describe('fillPatternRecursive', () => {
let trie: Trie | undefined;
beforeAll(() => {
return dictionaries.get(locale).then((loadedTrie) => {
trie = loadedTrie;
});
});
it('checks collisions', () => {
const pattern = new VerticalPattern(board, [
new Cell({ x: 2, y: 0, isEmpty: true, tile: new Tile({ character: 'k', isBlank: false }) }),
new Cell({ x: 2, y: 1, isEmpty: true, tile: new Tile({ character: 'o', isBlank: false }) }),
new Cell({ x: 2, y: 2, isEmpty: true, tile: new Tile({ character: 't', isBlank: false }) }),
]);
const results: Pattern[] = [];
const tiles = [new Tile({ character: 'ń', isBlank: false })];
fillPatternRecursive(results, trie!, config, pattern, pattern.toString(), tiles);
expect(results.length).toBe(0);
});
});