scrabble-solver 2.8.8 → 2.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.prettier-only.js +1 -1
- package/.prettierignore +3 -0
- package/.prettierrc +3 -3
- package/babel.config.js +1 -1
- package/lerna.json +1 -1
- package/package.json +6 -6
- package/packages/configs/package.json +3 -3
- package/packages/constants/package.json +1 -1
- package/packages/dictionaries/package-lock.json +2 -2
- package/packages/dictionaries/package.json +4 -4
- package/packages/logger/package-lock.json +2 -2
- package/packages/logger/package.json +1 -1
- package/packages/scrabble-solver/.next/BUILD_ID +1 -1
- package/packages/scrabble-solver/.next/build-manifest.json +10 -10
- package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
- package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
- package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
- package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/chunks/413.js +179 -44
- package/packages/scrabble-solver/.next/server/chunks/44.js +802 -0
- package/packages/scrabble-solver/.next/server/chunks/515.js +359 -95
- package/packages/scrabble-solver/.next/server/chunks/911.js +53 -23
- package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
- package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
- package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/500.html +2 -2
- package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/_error.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/solve.js +193 -927
- package/packages/scrabble-solver/.next/server/pages/api/solve.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/verify.js +217 -0
- package/packages/scrabble-solver/.next/server/pages/api/verify.js.nft.json +1 -0
- package/packages/scrabble-solver/.next/server/pages/index.html +3 -3
- package/packages/scrabble-solver/.next/server/pages/index.js +7 -1
- package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
- package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -0
- package/packages/scrabble-solver/.next/static/chunks/317-a33dd38e9b9a17ed.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/{404-8eb3ba4f0ba17e08.js → 404-90c624da3c83fd17.js} +1 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-f8f360878e1c2aff.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/index-ecea697d3e5d8a6f.js +1 -0
- package/packages/scrabble-solver/.next/static/css/64dc2ce1811912f1.css +1 -0
- package/packages/scrabble-solver/.next/static/css/{cdbc9e0afcff5473.css → ad2a08918868cad8.css} +1 -1
- package/packages/scrabble-solver/.next/static/yCxjzzYpw5JjJE53PO_s6/_buildManifest.js +1 -0
- package/packages/scrabble-solver/.next/static/{z3J3qmq1nazbDv_ENIkCo → yCxjzzYpw5JjJE53PO_s6}/_ssgManifest.js +0 -0
- package/packages/scrabble-solver/.next/trace +42 -41
- package/packages/scrabble-solver/package-lock.json +2 -2
- package/packages/scrabble-solver/package.json +8 -8
- package/packages/scrabble-solver/src/components/Badge/Badge.module.scss +13 -0
- package/packages/scrabble-solver/src/components/Badge/Badge.tsx +15 -0
- package/packages/scrabble-solver/src/components/Badge/index.ts +1 -0
- package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +33 -14
- package/packages/scrabble-solver/src/components/RemainingTiles/RemainingTiles.module.scss +8 -7
- package/packages/scrabble-solver/src/components/RemainingTiles/RemainingTiles.tsx +13 -4
- package/packages/scrabble-solver/src/components/Sidebar/Sidebar.tsx +2 -2
- package/packages/scrabble-solver/src/components/Sidebar/components/Section/Section.module.scss +0 -1
- package/packages/scrabble-solver/src/components/Sidebar/components/Section/Section.tsx +1 -1
- package/packages/scrabble-solver/src/components/SquareButton/SquareButton.module.scss +5 -0
- package/packages/scrabble-solver/src/components/Words/Words.module.scss +35 -0
- package/packages/scrabble-solver/src/components/Words/Words.tsx +57 -0
- package/packages/scrabble-solver/src/components/Words/index.ts +1 -0
- package/packages/scrabble-solver/src/components/index.ts +2 -0
- package/packages/scrabble-solver/src/i18n/de.json +4 -1
- package/packages/scrabble-solver/src/i18n/en.json +4 -1
- package/packages/scrabble-solver/src/i18n/es.json +4 -1
- package/packages/scrabble-solver/src/i18n/fr.json +4 -1
- package/packages/scrabble-solver/src/i18n/pl.json +4 -1
- package/packages/scrabble-solver/src/icons/BookHalf.svg +4 -0
- package/packages/scrabble-solver/src/icons/Check.svg +4 -0
- package/packages/scrabble-solver/src/icons/Cross.svg +2 -2
- package/packages/scrabble-solver/src/icons/CrossFill.svg +4 -0
- package/packages/scrabble-solver/src/icons/index.ts +3 -0
- package/packages/scrabble-solver/src/pages/api/solve.ts +2 -3
- package/packages/scrabble-solver/src/pages/api/verify.ts +71 -0
- package/packages/scrabble-solver/src/pages/index.tsx +5 -0
- package/packages/scrabble-solver/src/sdk/index.ts +1 -0
- package/packages/scrabble-solver/src/sdk/verify.ts +24 -0
- package/packages/scrabble-solver/src/state/rootReducer.ts +2 -0
- package/packages/scrabble-solver/src/state/sagas.ts +33 -6
- package/packages/scrabble-solver/src/state/selectors.ts +8 -0
- package/packages/scrabble-solver/src/state/slices/index.ts +2 -0
- package/packages/scrabble-solver/src/state/slices/verifyInitialState.ts +12 -0
- package/packages/scrabble-solver/src/state/slices/verifySlice.ts +31 -0
- package/packages/scrabble-solver/src/styles/variables.scss +2 -1
- package/packages/scrabble-solver/src/types/index.ts +4 -1
- package/packages/solver/build/fillPattern.d.ts +5 -0
- package/packages/solver/build/fillPattern.js +52 -0
- package/packages/solver/build/generateEndIndices.d.ts +3 -0
- package/packages/solver/build/generateEndIndices.js +9 -0
- package/packages/solver/build/generateHorizontalPatterns.d.ts +3 -0
- package/packages/solver/build/generateHorizontalPatterns.js +18 -0
- package/packages/solver/build/generatePattern.d.ts +8 -0
- package/packages/solver/build/generatePattern.js +22 -0
- package/packages/solver/build/generatePatterns.d.ts +3 -0
- package/packages/solver/build/generatePatterns.js +13 -0
- package/packages/solver/build/generateStartIndices.d.ts +3 -0
- package/packages/solver/build/generateStartIndices.js +9 -0
- package/packages/solver/build/generateVectors.d.ts +6 -0
- package/packages/solver/build/generateVectors.js +8 -0
- package/packages/solver/build/generateVerticalPatterns.d.ts +3 -0
- package/packages/solver/build/generateVerticalPatterns.js +18 -0
- package/packages/solver/build/getCellsScore.d.ts +3 -0
- package/packages/solver/build/getCellsScore.js +16 -0
- package/packages/solver/build/getPatternHash.d.ts +3 -0
- package/packages/solver/build/getPatternHash.js +13 -0
- package/packages/solver/build/getPatternScore.d.ts +3 -0
- package/packages/solver/build/getPatternScore.js +15 -0
- package/packages/solver/build/getUniquePatterns.js +5 -11
- package/packages/solver/build/index.d.ts +1 -1
- package/packages/solver/build/index.js +3 -3
- package/packages/solver/build/solve.d.ts +4 -0
- package/packages/solver/build/solve.js +23 -0
- package/packages/solver/package-lock.json +2 -2
- package/packages/solver/package.json +5 -5
- package/packages/solver/src/fillPattern.test.ts +107 -0
- package/packages/solver/src/fillPattern.ts +70 -0
- package/packages/solver/src/generateEndIndices.test.ts +18 -0
- package/packages/solver/src/generateEndIndices.ts +10 -0
- package/packages/solver/src/generateHorizontalPatterns.test.ts +31 -0
- package/packages/solver/src/generateHorizontalPatterns.ts +17 -0
- package/packages/solver/src/generatePattern.ts +35 -0
- package/packages/solver/src/generatePatterns.ts +13 -0
- package/packages/solver/src/generateStartIndices.test.ts +14 -0
- package/packages/solver/src/generateStartIndices.ts +10 -0
- package/packages/solver/src/generateVectors.test.ts +12 -0
- package/packages/solver/src/generateVectors.ts +15 -0
- package/packages/solver/src/generateVerticalPatterns.test.ts +32 -0
- package/packages/solver/src/generateVerticalPatterns.ts +17 -0
- package/packages/solver/src/getCellsScore.ts +22 -0
- package/packages/solver/src/getPatternHash.test.ts +17 -0
- package/packages/solver/src/getPatternHash.ts +14 -0
- package/packages/solver/src/getPatternScore.test.ts +60 -0
- package/packages/solver/src/getPatternScore.ts +15 -0
- package/packages/solver/src/getUniquePatterns.ts +1 -10
- package/packages/solver/src/index.ts +1 -1
- package/packages/solver/src/{Solver.test.ts → solve.test.ts} +14 -13
- package/packages/solver/src/solve.ts +25 -0
- package/packages/types/build/Board.d.ts +1 -0
- package/packages/types/build/Board.js +17 -1
- package/packages/types/build/Config.js +1 -1
- package/packages/types/build/FinalPattern.d.ts +7 -0
- package/packages/types/build/FinalPattern.js +16 -0
- package/packages/types/build/HorizontalPattern.js +2 -5
- package/packages/types/build/Pattern.d.ts +1 -4
- package/packages/types/build/Pattern.js +2 -5
- package/packages/types/build/Result.js +3 -5
- package/packages/types/build/Tile.d.ts +2 -2
- package/packages/types/build/VerticalPattern.js +2 -5
- package/packages/types/build/index.d.ts +1 -0
- package/packages/types/build/index.js +3 -1
- package/packages/types/package.json +2 -2
- package/packages/types/src/Board.ts +23 -1
- package/packages/types/src/Config.ts +1 -1
- package/packages/types/src/FinalPattern.ts +16 -0
- package/packages/types/src/HorizontalPattern.ts +5 -5
- package/packages/types/src/Pattern.ts +5 -5
- package/packages/types/src/Result.ts +3 -5
- package/packages/types/src/Tile.ts +2 -2
- package/packages/types/src/VerticalPattern.ts +5 -5
- package/packages/types/src/index.ts +1 -0
- package/packages/word-definitions/package-lock.json +2 -2
- package/packages/word-definitions/package.json +2 -2
- package/packages/word-lists/package-lock.json +2 -2
- package/packages/word-lists/package.json +2 -2
- package/packages/scrabble-solver/.next/static/chunks/615-d258f6c528c18622.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-4a663fd3d5ca4524.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/index-1a9826d740cc8830.js +0 -1
- package/packages/scrabble-solver/.next/static/css/180c6c26317ac90f.css +0 -1
- package/packages/scrabble-solver/.next/static/z3J3qmq1nazbDv_ENIkCo/_buildManifest.js +0 -1
- package/packages/solver/build/PatternsFiller.d.ts +0 -12
- package/packages/solver/build/PatternsFiller.js +0 -70
- package/packages/solver/build/PatternsGenerator.d.ts +0 -32
- package/packages/solver/build/PatternsGenerator.js +0 -66
- package/packages/solver/build/ScoresCalculator.d.ts +0 -17
- package/packages/solver/build/ScoresCalculator.js +0 -37
- package/packages/solver/build/Solver.d.ts +0 -10
- package/packages/solver/build/Solver.js +0 -30
- package/packages/solver/src/PatternsFiller.test.ts +0 -92
- package/packages/solver/src/PatternsFiller.ts +0 -91
- package/packages/solver/src/PatternsGenerator.test.ts +0 -89
- package/packages/solver/src/PatternsGenerator.ts +0 -103
- package/packages/solver/src/ScoresCalculator.test.ts +0 -70
- package/packages/solver/src/ScoresCalculator.ts +0 -52
- package/packages/solver/src/Solver.ts +0 -39
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Trie } from '@kamilmielnik/trie';
|
|
2
|
+
import { literaki } from '@scrabble-solver/configs';
|
|
3
|
+
import { dictionaries } from '@scrabble-solver/dictionaries';
|
|
4
|
+
import { Board, Cell, FinalPattern, Locale, Pattern, Tile, VerticalPattern } from '@scrabble-solver/types';
|
|
5
|
+
|
|
6
|
+
import fillPattern, { fillPatternRecursive } from './fillPattern';
|
|
7
|
+
|
|
8
|
+
const board = Board.fromStringArray([' t ', 'do ', ' ']);
|
|
9
|
+
const locale = Locale.PL_PL;
|
|
10
|
+
const config = literaki[locale];
|
|
11
|
+
|
|
12
|
+
describe('fillPattern', () => {
|
|
13
|
+
let trie: Trie | undefined;
|
|
14
|
+
|
|
15
|
+
beforeAll(() => {
|
|
16
|
+
return dictionaries.get(locale).then((loadedTrie) => {
|
|
17
|
+
trie = loadedTrie;
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('fills patterns', () => {
|
|
22
|
+
const pattern = new VerticalPattern(board, [
|
|
23
|
+
new Cell({ x: 0, y: 0 }),
|
|
24
|
+
new Cell({ x: 0, y: 1, tile: new Tile({ character: 'd', isBlank: false }) }),
|
|
25
|
+
new Cell({ x: 0, y: 2 }),
|
|
26
|
+
]);
|
|
27
|
+
const tiles = [
|
|
28
|
+
new Tile({ character: 'o', isBlank: false }),
|
|
29
|
+
new Tile({ character: 'a', isBlank: false }),
|
|
30
|
+
new Tile({ character: 'd', isBlank: false }),
|
|
31
|
+
];
|
|
32
|
+
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
|
|
33
|
+
|
|
34
|
+
expect(filledPatterns.length).toBe(1);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('fills patterns with blanks', () => {
|
|
38
|
+
const pattern = new VerticalPattern(board, [board.rows[0][1], board.rows[1][1], board.rows[2][1]]);
|
|
39
|
+
const tiles = [new Tile({ character: ' ', isBlank: true }), new Tile({ character: 'ó', isBlank: false })];
|
|
40
|
+
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
|
|
41
|
+
|
|
42
|
+
expect(filledPatterns.map(String)).toEqual([
|
|
43
|
+
'toć',
|
|
44
|
+
'tog',
|
|
45
|
+
'toi',
|
|
46
|
+
'tok',
|
|
47
|
+
'tom',
|
|
48
|
+
'ton',
|
|
49
|
+
'toń',
|
|
50
|
+
'top',
|
|
51
|
+
'tor',
|
|
52
|
+
'tos',
|
|
53
|
+
'toy',
|
|
54
|
+
'toż',
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('does not modify filled patterns', () => {
|
|
59
|
+
const pattern = new FinalPattern(
|
|
60
|
+
new VerticalPattern(board, [
|
|
61
|
+
new Cell({ x: 0, y: 0, isEmpty: false, tile: new Tile({ character: 'o', isBlank: false }) }),
|
|
62
|
+
new Cell({ x: 0, y: 1, isEmpty: false, tile: new Tile({ character: 'k', isBlank: false }) }),
|
|
63
|
+
new Cell({ x: 0, y: 2, isEmpty: false, tile: new Tile({ character: 'o', isBlank: false }) }),
|
|
64
|
+
]),
|
|
65
|
+
);
|
|
66
|
+
const tiles = [new Tile({ character: 'ń', isBlank: false })];
|
|
67
|
+
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
|
|
68
|
+
|
|
69
|
+
expect(filledPatterns.length).toBe(1);
|
|
70
|
+
expect(filledPatterns[0]).toEqual(pattern);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('does not accept non-placeable filled patterns', () => {
|
|
74
|
+
const pattern = new VerticalPattern(board, [
|
|
75
|
+
new Cell({ x: 0, y: 0, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
|
|
76
|
+
new Cell({ x: 0, y: 1, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
|
|
77
|
+
new Cell({ x: 0, y: 2, isEmpty: false, tile: new Tile({ character: 'd', isBlank: false }) }),
|
|
78
|
+
]);
|
|
79
|
+
const tiles = [new Tile({ character: 'ń', isBlank: false })];
|
|
80
|
+
const filledPatterns = fillPattern(trie!, config, pattern, tiles);
|
|
81
|
+
|
|
82
|
+
expect(filledPatterns.length).toBe(0);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('fillPatternRecursive', () => {
|
|
87
|
+
let trie: Trie | undefined;
|
|
88
|
+
|
|
89
|
+
beforeAll(() => {
|
|
90
|
+
return dictionaries.get(locale).then((loadedTrie) => {
|
|
91
|
+
trie = loadedTrie;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('checks collisions', () => {
|
|
96
|
+
const pattern = new VerticalPattern(board, [
|
|
97
|
+
new Cell({ x: 2, y: 0, isEmpty: true, tile: new Tile({ character: 'k', isBlank: false }) }),
|
|
98
|
+
new Cell({ x: 2, y: 1, isEmpty: true, tile: new Tile({ character: 'o', isBlank: false }) }),
|
|
99
|
+
new Cell({ x: 2, y: 2, isEmpty: true, tile: new Tile({ character: 't', isBlank: false }) }),
|
|
100
|
+
]);
|
|
101
|
+
const results: Pattern[] = [];
|
|
102
|
+
const tiles = [new Tile({ character: 'ń', isBlank: false })];
|
|
103
|
+
fillPatternRecursive(results, trie!, config, pattern, pattern.toString(), tiles);
|
|
104
|
+
|
|
105
|
+
expect(results.length).toBe(0);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* eslint-disable max-params, max-statements */
|
|
2
|
+
import { Trie } from '@kamilmielnik/trie';
|
|
3
|
+
import { EMPTY_CELL } from '@scrabble-solver/constants';
|
|
4
|
+
import { Config, FinalPattern, Pattern, Tile } from '@scrabble-solver/types';
|
|
5
|
+
|
|
6
|
+
const fillPattern = (trie: Trie, config: Config, pattern: Pattern, tiles: Tile[]): Pattern[] => {
|
|
7
|
+
if (pattern.getEmptyCellsCount() > tiles.length) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const results: Pattern[] = [];
|
|
12
|
+
|
|
13
|
+
fillPatternRecursive(results, trie, config, pattern, pattern.toString(), tiles);
|
|
14
|
+
|
|
15
|
+
return results;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const fillPatternRecursive = (
|
|
19
|
+
/** gets mutated when this function is called */
|
|
20
|
+
results: Pattern[],
|
|
21
|
+
trie: Trie,
|
|
22
|
+
config: Config,
|
|
23
|
+
pattern: Pattern,
|
|
24
|
+
word: string,
|
|
25
|
+
tiles: Tile[],
|
|
26
|
+
): void => {
|
|
27
|
+
const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
|
|
28
|
+
|
|
29
|
+
if (indexOfFirstCellWithoutTile === -1) {
|
|
30
|
+
if (trie.has(word) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
|
|
31
|
+
results.push(new FinalPattern(pattern.clone()));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (let index = 0; index < tiles.length; ++index) {
|
|
38
|
+
const tile = tiles[index];
|
|
39
|
+
const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
|
|
40
|
+
|
|
41
|
+
pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
|
|
42
|
+
|
|
43
|
+
const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
|
|
44
|
+
const indexOfFirstEmptyLetter = word.indexOf(EMPTY_CELL);
|
|
45
|
+
const prefix = word.substring(0, indexOfFirstEmptyLetter);
|
|
46
|
+
const suffix = word.substring(indexOfFirstEmptyLetter + 1);
|
|
47
|
+
const characters = tile.isBlank ? config.alphabet : [tile.character];
|
|
48
|
+
|
|
49
|
+
for (const character of characters) {
|
|
50
|
+
const newWordPrefix = prefix + character;
|
|
51
|
+
const newWord = newWordPrefix + suffix;
|
|
52
|
+
|
|
53
|
+
tile.character = character;
|
|
54
|
+
|
|
55
|
+
if (indexOfNextCellWithoutTile === -1) {
|
|
56
|
+
if (trie.has(newWord) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
|
|
57
|
+
results.push(new FinalPattern(pattern.clone()));
|
|
58
|
+
}
|
|
59
|
+
} else if (trie.hasPrefix(newWordPrefix)) {
|
|
60
|
+
tiles.splice(index, 1);
|
|
61
|
+
fillPatternRecursive(results, trie, config, pattern, newWord, tiles);
|
|
62
|
+
tiles.splice(index, 0, tile);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default fillPattern;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Cell } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generateEndIndices from './generateEndIndices';
|
|
4
|
+
|
|
5
|
+
describe('generateEndIndices', () => {
|
|
6
|
+
const emptyCell: Cell = { hasTile: () => false } as Cell;
|
|
7
|
+
const filledCell: Cell = { hasTile: () => true } as Cell;
|
|
8
|
+
|
|
9
|
+
it('finds indices where a new word can end - XXOOOX', () => {
|
|
10
|
+
const cells = [filledCell, filledCell, emptyCell, emptyCell, emptyCell, filledCell];
|
|
11
|
+
expect(generateEndIndices(cells, 3)).toEqual([5]);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('finds indices where a new word can end - XXOOOXO', () => {
|
|
15
|
+
const cells = [filledCell, filledCell, emptyCell, emptyCell, emptyCell, filledCell, emptyCell];
|
|
16
|
+
expect(generateEndIndices(cells, 3)).toEqual([5, 6]);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Cell } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
const generateEndIndices = (cells: Cell[], startIndex: number): number[] => {
|
|
4
|
+
return Array(cells.length - startIndex - 1)
|
|
5
|
+
.fill(0)
|
|
6
|
+
.map((_, endIndex) => endIndex + startIndex + 1)
|
|
7
|
+
.filter((endIndex) => endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile());
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default generateEndIndices;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EMPTY_CELL } from '@scrabble-solver/constants';
|
|
2
|
+
import { Board, Config } from '@scrabble-solver/types';
|
|
3
|
+
|
|
4
|
+
import generateHorizontalPatterns from './generateHorizontalPatterns';
|
|
5
|
+
|
|
6
|
+
const board = Board.fromStringArray([' t ', 'do ', ' ']);
|
|
7
|
+
|
|
8
|
+
const config = {
|
|
9
|
+
boardHeight: 3,
|
|
10
|
+
boardWidth: 3,
|
|
11
|
+
maximumCharactersCount: 7,
|
|
12
|
+
} as Config;
|
|
13
|
+
|
|
14
|
+
describe('generateHorizontalPatterns', () => {
|
|
15
|
+
it('generates some horizontal patterns', () => {
|
|
16
|
+
expect(generateHorizontalPatterns(config, board).length).toBeGreaterThan(0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('generates proper horizontal patterns', () => {
|
|
20
|
+
const horizontal = generateHorizontalPatterns(config, board);
|
|
21
|
+
expect(horizontal.map(({ cells }) => cells.map(String))).toEqual([
|
|
22
|
+
[EMPTY_CELL, 't'],
|
|
23
|
+
[EMPTY_CELL, 't', EMPTY_CELL],
|
|
24
|
+
['t', EMPTY_CELL],
|
|
25
|
+
['d', 'o', EMPTY_CELL],
|
|
26
|
+
[EMPTY_CELL, EMPTY_CELL],
|
|
27
|
+
[EMPTY_CELL, EMPTY_CELL, EMPTY_CELL],
|
|
28
|
+
[EMPTY_CELL, EMPTY_CELL],
|
|
29
|
+
]);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Board, Config, HorizontalPattern, Pattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generatePattern from './generatePattern';
|
|
4
|
+
import generateVectors from './generateVectors';
|
|
5
|
+
|
|
6
|
+
const generateHorizontalPatterns = (config: Config, board: Board): Pattern[] => {
|
|
7
|
+
const getNthVector = (index: number) => board.getRow(index);
|
|
8
|
+
const vectorsCount = config.boardHeight;
|
|
9
|
+
const horizontalVectors = generateVectors({ getNthVector, vectorsCount });
|
|
10
|
+
const horizontalPatterns = horizontalVectors.flatMap((cells) => {
|
|
11
|
+
return generatePattern({ board, config, PatternModel: HorizontalPattern, cells });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return horizontalPatterns;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default generateHorizontalPatterns;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Board, Cell, Config, Pattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generateEndIndices from './generateEndIndices';
|
|
4
|
+
import generateStartIndices from './generateStartIndices';
|
|
5
|
+
|
|
6
|
+
const generatePattern = <P extends Pattern>({
|
|
7
|
+
board,
|
|
8
|
+
cells,
|
|
9
|
+
config,
|
|
10
|
+
PatternModel,
|
|
11
|
+
}: {
|
|
12
|
+
board: Board;
|
|
13
|
+
cells: Cell[];
|
|
14
|
+
config: Config;
|
|
15
|
+
PatternModel: new (board: Board, cells: Cell[]) => P;
|
|
16
|
+
}): P[] => {
|
|
17
|
+
const startIndices = generateStartIndices(cells);
|
|
18
|
+
|
|
19
|
+
return startIndices.flatMap((startIndex) => {
|
|
20
|
+
const endIndices = generateEndIndices(cells, startIndex);
|
|
21
|
+
const patterns: P[] = [];
|
|
22
|
+
|
|
23
|
+
for (const endIndex of endIndices) {
|
|
24
|
+
const pattern = new PatternModel(board, cells.slice(startIndex, endIndex + 1));
|
|
25
|
+
|
|
26
|
+
if (pattern.canBePlaced(config)) {
|
|
27
|
+
patterns.push(pattern);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return patterns;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default generatePattern;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Board, Config, Pattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generateHorizontalPatterns from './generateHorizontalPatterns';
|
|
4
|
+
import generateVerticalPatterns from './generateVerticalPatterns';
|
|
5
|
+
|
|
6
|
+
const generatePatterns = (config: Config, board: Board): Pattern[] => {
|
|
7
|
+
const horizontalPatterns = generateHorizontalPatterns(config, board);
|
|
8
|
+
const verticalPatterns = generateVerticalPatterns(config, board);
|
|
9
|
+
|
|
10
|
+
return horizontalPatterns.concat(verticalPatterns);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default generatePatterns;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Cell } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generateStartIndices from './generateStartIndices';
|
|
4
|
+
|
|
5
|
+
describe('generateStartIndices', () => {
|
|
6
|
+
const emptyCell: Cell = { hasTile: () => false } as Cell;
|
|
7
|
+
const filledCell: Cell = { hasTile: () => true } as Cell;
|
|
8
|
+
|
|
9
|
+
it('finds indices where a new word can start', () => {
|
|
10
|
+
const cells = [filledCell, filledCell, emptyCell, emptyCell, emptyCell, filledCell];
|
|
11
|
+
const startIndices = generateStartIndices(cells);
|
|
12
|
+
expect(startIndices).toEqual([0, 3, 4]);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Cell } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
const generateStartIndices = (cells: Cell[]): number[] => {
|
|
4
|
+
return Array(cells.length - 1)
|
|
5
|
+
.fill(0)
|
|
6
|
+
.map((_, startIndex) => startIndex)
|
|
7
|
+
.filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default generateStartIndices;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import generateVectors from './generateVectors';
|
|
2
|
+
|
|
3
|
+
describe('generateVectors', () => {
|
|
4
|
+
it('generates given number of vectors', () => {
|
|
5
|
+
const vectors = generateVectors({
|
|
6
|
+
getNthVector: () => [],
|
|
7
|
+
vectorsCount: 3,
|
|
8
|
+
});
|
|
9
|
+
expect(vectors.length).toBe(3);
|
|
10
|
+
expect(vectors).toEqual([[], [], []]);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Cell } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
const generateVectors = ({
|
|
4
|
+
getNthVector,
|
|
5
|
+
vectorsCount,
|
|
6
|
+
}: {
|
|
7
|
+
getNthVector: (index: number) => Cell[];
|
|
8
|
+
vectorsCount: number;
|
|
9
|
+
}): Cell[][] => {
|
|
10
|
+
return Array(vectorsCount)
|
|
11
|
+
.fill(0)
|
|
12
|
+
.map((_, index) => getNthVector(index));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default generateVectors;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { EMPTY_CELL } from '@scrabble-solver/constants';
|
|
2
|
+
import { Board, Config } from '@scrabble-solver/types';
|
|
3
|
+
|
|
4
|
+
import generateVerticalPatterns from './generateVerticalPatterns';
|
|
5
|
+
|
|
6
|
+
const board = Board.fromStringArray([' t ', 'do ', ' ']);
|
|
7
|
+
|
|
8
|
+
const config = {
|
|
9
|
+
boardHeight: 3,
|
|
10
|
+
boardWidth: 3,
|
|
11
|
+
maximumCharactersCount: 7,
|
|
12
|
+
} as Config;
|
|
13
|
+
|
|
14
|
+
describe('generateVerticalPatterns', () => {
|
|
15
|
+
it('generates some vertical patterns', () => {
|
|
16
|
+
expect(generateVerticalPatterns(config, board).length).toBeGreaterThan(0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('generates proper vertical patterns', () => {
|
|
20
|
+
const vertical = generateVerticalPatterns(config, board);
|
|
21
|
+
|
|
22
|
+
expect(vertical.map(({ cells }) => cells.map(String))).toEqual([
|
|
23
|
+
[EMPTY_CELL, 'd'],
|
|
24
|
+
[EMPTY_CELL, 'd', EMPTY_CELL],
|
|
25
|
+
['d', EMPTY_CELL],
|
|
26
|
+
['t', 'o', EMPTY_CELL],
|
|
27
|
+
[EMPTY_CELL, EMPTY_CELL],
|
|
28
|
+
[EMPTY_CELL, EMPTY_CELL, EMPTY_CELL],
|
|
29
|
+
[EMPTY_CELL, EMPTY_CELL],
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Board, Config, Pattern, VerticalPattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import generatePattern from './generatePattern';
|
|
4
|
+
import generateVectors from './generateVectors';
|
|
5
|
+
|
|
6
|
+
const generateVerticalPatterns = (config: Config, board: Board): Pattern[] => {
|
|
7
|
+
const getNthVector = (index: number) => board.getColumn(index);
|
|
8
|
+
const vectorsCount = config.boardWidth;
|
|
9
|
+
const verticalVectors = generateVectors({ getNthVector, vectorsCount });
|
|
10
|
+
const verticalPatterns = verticalVectors.flatMap((cells) => {
|
|
11
|
+
return generatePattern({ board, config, PatternModel: VerticalPattern, cells });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return verticalPatterns;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default generateVerticalPatterns;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NO_BONUS } from '@scrabble-solver/constants';
|
|
2
|
+
import { Cell, Config } from '@scrabble-solver/types';
|
|
3
|
+
|
|
4
|
+
const getCellsScore = (config: Config, cells: Cell[]): number => {
|
|
5
|
+
const total = cells.reduce(
|
|
6
|
+
({ multiplier, score }, cell: Cell): { multiplier: number; score: number } => {
|
|
7
|
+
const bonus = config.getCellBonus(cell);
|
|
8
|
+
const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(config, cell) ? bonus.value : NO_BONUS;
|
|
9
|
+
const characterScore = cell.tile.isBlank ? config.blankScore : config.pointsMap[cell.tile.character];
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
multiplier: multiplier * wordMultiplier,
|
|
13
|
+
score: score + characterScore * characterMultiplier,
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
{ multiplier: 1, score: 0 },
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return total.score * total.multiplier;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default getCellsScore;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Board, Cell, Pattern, Tile } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import getPatternHash from './getPatternHash';
|
|
4
|
+
|
|
5
|
+
describe('getPatternHash', () => {
|
|
6
|
+
const board = Board.fromStringArray([' t ', 'do ', ' ']);
|
|
7
|
+
|
|
8
|
+
it('hashes blanks', () => {
|
|
9
|
+
const pattern = new Pattern(board, [
|
|
10
|
+
new Cell({ x: 0, y: 0, tile: new Tile({ character: 'a', isBlank: false }) }),
|
|
11
|
+
new Cell({ x: 0, y: 1, tile: new Tile({ character: 'b', isBlank: true }) }),
|
|
12
|
+
new Cell({ x: 0, y: 2, tile: new Tile({ character: 'c', isBlank: false }) }),
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
expect(getPatternHash(pattern)).toBe('0,0,a-0,1,b!-0,2,c');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Pattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
const getPatternHash = (pattern: Pattern): string => {
|
|
4
|
+
return pattern.cells
|
|
5
|
+
.map((cell) => {
|
|
6
|
+
const blank = cell.tile.isBlank ? '!' : '';
|
|
7
|
+
const tile = cell.tile.character + blank;
|
|
8
|
+
// eslint-disable-next-line prefer-template
|
|
9
|
+
return cell.x + ',' + cell.y + ',' + tile;
|
|
10
|
+
})
|
|
11
|
+
.join('-');
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default getPatternHash;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { literaki } from '@scrabble-solver/configs';
|
|
2
|
+
import { Board, Cell, HorizontalPattern, Locale, Pattern, Tile, VerticalPattern } from '@scrabble-solver/types';
|
|
3
|
+
|
|
4
|
+
import getPatternScore from './getPatternScore';
|
|
5
|
+
|
|
6
|
+
const config = literaki[Locale.PL_PL];
|
|
7
|
+
const board = Board.fromStringArray([
|
|
8
|
+
' kasom ',
|
|
9
|
+
' i ',
|
|
10
|
+
' napiją ',
|
|
11
|
+
' w i ',
|
|
12
|
+
' krabim ',
|
|
13
|
+
' z ',
|
|
14
|
+
' ę eh ',
|
|
15
|
+
'f s srać ',
|
|
16
|
+
'i z t s ',
|
|
17
|
+
'knebel e ',
|
|
18
|
+
'a ew warcz',
|
|
19
|
+
'ł żyło wody ',
|
|
20
|
+
'o pecyj chu',
|
|
21
|
+
' y ',
|
|
22
|
+
' t ',
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
describe('getPatternScore', () => {
|
|
26
|
+
it('gives proper score without collisions', () => {
|
|
27
|
+
const pattern = new Pattern(board, [
|
|
28
|
+
new Cell({ x: 0, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: true }),
|
|
29
|
+
new Cell({ x: 1, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
30
|
+
new Cell({ x: 2, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
31
|
+
new Cell({ x: 3, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
32
|
+
new Cell({ x: 4, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
33
|
+
new Cell({ x: 5, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
34
|
+
new Cell({ x: 6, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
|
|
35
|
+
new Cell({ x: 7, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: false }),
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
expect(getPatternScore(config, pattern)).toBe(128);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('gives proper score with collisions', () => {
|
|
42
|
+
const pattern = new VerticalPattern(board, [
|
|
43
|
+
new Cell({ x: 2, y: 11, tile: new Tile({ character: 'l' }), isEmpty: true }),
|
|
44
|
+
new Cell({ x: 2, y: 12, tile: new Tile({ character: 'i' }), isEmpty: true }),
|
|
45
|
+
new Cell({ x: 2, y: 13, tile: new Tile({ character: 'n' }), isEmpty: true }),
|
|
46
|
+
new Cell({ x: 2, y: 14, tile: new Tile({ character: 'o' }), isEmpty: true }),
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
expect(getPatternScore(config, pattern)).toBe(44);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('gives proper score for blank', () => {
|
|
53
|
+
const pattern = new HorizontalPattern(board, [
|
|
54
|
+
new Cell({ x: 13, y: 14, tile: new Tile({ character: 'o', isBlank: true }), isEmpty: true }),
|
|
55
|
+
new Cell({ x: 12, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
expect(getPatternScore(config, pattern)).toBe(2);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Config, Pattern } from '@scrabble-solver/types';
|
|
2
|
+
|
|
3
|
+
import getCellsScore from './getCellsScore';
|
|
4
|
+
|
|
5
|
+
const getPatternScore = (config: Config, pattern: Pattern) => {
|
|
6
|
+
const areAllTilesUsed = pattern.getEmptyCellsCount() === config.maximumCharactersCount;
|
|
7
|
+
const bonusScore = areAllTilesUsed ? config.allTilesBonusScore : 0;
|
|
8
|
+
const score = pattern
|
|
9
|
+
.getCollisions()
|
|
10
|
+
.reduce((sum, collision) => sum + getCellsScore(config, collision.cells), getCellsScore(config, pattern.cells));
|
|
11
|
+
|
|
12
|
+
return score + bonusScore;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default getPatternScore;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { Pattern } from '@scrabble-solver/types';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
return pattern.cells
|
|
5
|
-
.map((cell) => {
|
|
6
|
-
const blank = cell.tile.isBlank ? '!' : '';
|
|
7
|
-
const tile = cell.tile.character + blank;
|
|
8
|
-
// eslint-disable-next-line prefer-template
|
|
9
|
-
return cell.x + ',' + cell.y + ',' + tile;
|
|
10
|
-
})
|
|
11
|
-
.join('-');
|
|
12
|
-
};
|
|
3
|
+
import getPatternHash from './getPatternHash';
|
|
13
4
|
|
|
14
5
|
const getUniquePatterns = (patterns: Pattern[]): Pattern[] => {
|
|
15
6
|
const hashes = new Set<string>();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from './
|
|
1
|
+
export { default as solve } from './solve';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { Trie } from '@kamilmielnik/trie';
|
|
1
2
|
import { literaki, scrabble } from '@scrabble-solver/configs';
|
|
2
3
|
import { dictionaries } from '@scrabble-solver/dictionaries';
|
|
3
4
|
import { Board, Locale, Result, Tile } from '@scrabble-solver/types';
|
|
4
5
|
|
|
5
|
-
import
|
|
6
|
+
import solve from './solve';
|
|
6
7
|
|
|
7
8
|
const generateTiles = (characters: string[]): Tile[] => {
|
|
8
9
|
return characters.map((character) => new Tile({ character, isBlank: false }));
|
|
@@ -15,14 +16,14 @@ const getBestResult = ([firstResult, ...results]: Result[]): Result => {
|
|
|
15
16
|
);
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
describe('
|
|
19
|
+
describe('solve - PL', () => {
|
|
19
20
|
const locale = Locale.PL_PL;
|
|
20
21
|
const config = literaki[locale];
|
|
21
|
-
let
|
|
22
|
+
let trie: Trie | undefined;
|
|
22
23
|
|
|
23
24
|
beforeAll(() => {
|
|
24
|
-
return dictionaries.get(locale).then((
|
|
25
|
-
|
|
25
|
+
return dictionaries.get(locale).then((loadedTrie) => {
|
|
26
|
+
trie = loadedTrie;
|
|
26
27
|
});
|
|
27
28
|
});
|
|
28
29
|
|
|
@@ -45,7 +46,7 @@ describe('Solver - PL', () => {
|
|
|
45
46
|
' ',
|
|
46
47
|
]);
|
|
47
48
|
const tiles = generateTiles(['l', 'i', 'n', 'o']);
|
|
48
|
-
const results =
|
|
49
|
+
const results = solve(trie!, config, board, tiles);
|
|
49
50
|
expect(results.length).toBe(61);
|
|
50
51
|
});
|
|
51
52
|
|
|
@@ -68,7 +69,7 @@ describe('Solver - PL', () => {
|
|
|
68
69
|
' ',
|
|
69
70
|
]);
|
|
70
71
|
const tiles = generateTiles(['a', 'a', 'ą', 'r', 't', 'w', 'z']);
|
|
71
|
-
const results =
|
|
72
|
+
const results = solve(trie!, config, board, tiles);
|
|
72
73
|
const bestResult = getBestResult(results);
|
|
73
74
|
expect(bestResult.word).toBe('zmartwychwstałą');
|
|
74
75
|
expect(bestResult.points).toBe(682);
|
|
@@ -93,21 +94,21 @@ describe('Solver - PL', () => {
|
|
|
93
94
|
'ar ń m ',
|
|
94
95
|
]);
|
|
95
96
|
const tiles = generateTiles(['ą', 'c', 'h', 't', 'w', 'w', 'z']);
|
|
96
|
-
const results =
|
|
97
|
+
const results = solve(trie!, config, board, tiles);
|
|
97
98
|
const bestResult = getBestResult(results);
|
|
98
99
|
expect(bestResult.word).toBe('zmartwychwstałą');
|
|
99
100
|
expect(bestResult.points).toBe(1157);
|
|
100
101
|
});
|
|
101
102
|
});
|
|
102
103
|
|
|
103
|
-
describe('
|
|
104
|
+
describe('solve - ES', () => {
|
|
104
105
|
const locale = Locale.ES_ES;
|
|
105
106
|
const config = scrabble[locale];
|
|
106
|
-
let
|
|
107
|
+
let trie: Trie | undefined;
|
|
107
108
|
|
|
108
109
|
beforeAll(() => {
|
|
109
|
-
return dictionaries.get(locale).then((
|
|
110
|
-
|
|
110
|
+
return dictionaries.get(locale).then((loadedTrie) => {
|
|
111
|
+
trie = loadedTrie;
|
|
111
112
|
});
|
|
112
113
|
});
|
|
113
114
|
|
|
@@ -130,7 +131,7 @@ describe('Solver - ES', () => {
|
|
|
130
131
|
' ',
|
|
131
132
|
]);
|
|
132
133
|
const tiles = generateTiles(['ll', 'a', 'n', 'a']);
|
|
133
|
-
const results =
|
|
134
|
+
const results = solve(trie!, config, board, tiles);
|
|
134
135
|
const bestResult = getBestResult(results);
|
|
135
136
|
expect(results.length).toBe(24);
|
|
136
137
|
expect(bestResult.points).toBe(22);
|