scrabble-solver 2.10.0 → 2.10.2
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/README.md +2 -2
- package/lerna.json +1 -1
- package/package.json +19 -19
- package/packages/configs/package-lock.json +45 -0
- package/packages/configs/package.json +3 -3
- package/packages/constants/build/index.js +1 -0
- package/packages/constants/package-lock.json +13 -0
- package/packages/constants/package.json +1 -1
- package/packages/constants/src/index.ts +1 -0
- package/packages/dictionaries/build/lib/createAsyncProxy.d.ts +1 -1
- package/packages/dictionaries/package-lock.json +2 -2
- package/packages/dictionaries/package.json +4 -4
- package/packages/logger/package-lock.json +8 -8
- package/packages/logger/package.json +1 -1
- package/packages/scrabble-solver/.next/BUILD_ID +1 -1
- package/packages/scrabble-solver/.next/build-manifest.json +19 -31
- 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-development/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/1.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/2.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/3.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/4.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/client-development/index.pack.old +0 -0
- 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/edge-server-production/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-development/0.pack +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-development/10.pack_ +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-development/5.pack_ +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-development/8.pack_ +0 -0
- package/packages/scrabble-solver/.next/cache/webpack/server-development/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/images-manifest.json +1 -1
- 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/required-server-files.json +1 -1
- package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
- package/packages/scrabble-solver/.next/server/chunks/131.js +1399 -117
- package/packages/scrabble-solver/.next/server/chunks/{515.js → 176.js} +850 -732
- package/packages/scrabble-solver/.next/server/chunks/210.js +122 -0
- package/packages/scrabble-solver/.next/server/chunks/{939.js → 290.js} +4 -3
- package/packages/scrabble-solver/.next/server/chunks/44.js +33 -33
- package/packages/scrabble-solver/.next/server/chunks/50.js +5 -9
- package/packages/scrabble-solver/.next/server/chunks/{413.js → 579.js} +184 -117
- package/packages/scrabble-solver/.next/server/chunks/664.js +537 -350
- package/packages/scrabble-solver/.next/server/chunks/859.js +56 -23
- package/packages/scrabble-solver/.next/server/chunks/865.js +1 -1
- package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
- package/packages/scrabble-solver/.next/server/middleware-react-loadable-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 +23 -5
- package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/_document.js +2 -2
- package/packages/scrabble-solver/.next/server/pages/_error.js +206 -25
- package/packages/scrabble-solver/.next/server/pages/_error.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js +11 -11
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale]/[word].js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js +10 -10
- package/packages/scrabble-solver/.next/server/pages/api/dictionary/[locale].js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/solve.js +34 -36
- package/packages/scrabble-solver/.next/server/pages/api/solve.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/verify.js +10 -10
- package/packages/scrabble-solver/.next/server/pages/api/verify.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/api/visit.js +3 -3
- package/packages/scrabble-solver/.next/server/pages/api/visit.js.nft.json +1 -1
- package/packages/scrabble-solver/.next/server/pages/index.html +2 -2
- package/packages/scrabble-solver/.next/server/pages/index.js +44 -128
- 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 +4 -4
- package/packages/scrabble-solver/.next/static/FjrbXpI5fkt4lmko-vL_7/_buildManifest.js +1 -0
- package/packages/scrabble-solver/.next/static/{vscqn7BEtAxJteWSwNnas → FjrbXpI5fkt4lmko-vL_7}/_ssgManifest.js +0 -0
- package/packages/scrabble-solver/.next/static/chunks/361-d16f336a9752a55a.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/724-eb48df4d1ba3df8b.js +5 -0
- package/packages/scrabble-solver/.next/static/chunks/amp.js +720 -0
- package/packages/scrabble-solver/.next/static/chunks/framework-2c79e2a64abdb08b.js +33 -0
- package/packages/scrabble-solver/.next/static/chunks/main-f11614d8aa7ee555.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/main.js +1076 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/404-24f9617eeb8d6dc1.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-959e495f0f221247.js +24 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/_app.js +2121 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/_error-8353112a01355ec2.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/_error.js +28 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/index-1e30dafa41bddb80.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/pages/index.js +5314 -0
- package/packages/scrabble-solver/.next/static/chunks/react-refresh.js +62 -0
- package/packages/scrabble-solver/.next/static/chunks/webpack-59c5c889f52620d6.js +1 -0
- package/packages/scrabble-solver/.next/static/chunks/webpack.js +1237 -0
- package/packages/scrabble-solver/.next/static/css/aafd07997120f1e4.css +1 -0
- package/packages/scrabble-solver/.next/static/css/c8d26240c04079b9.css +1 -0
- package/packages/scrabble-solver/.next/static/css/eb9d57f7103525ab.css +1 -0
- package/packages/scrabble-solver/.next/static/development/_buildManifest.js +1 -0
- package/packages/scrabble-solver/.next/static/development/_ssgManifest.js +1 -0
- package/packages/scrabble-solver/.next/static/webpack/fb4b50d5e70ee127.webpack.hot-update.json +1 -0
- package/packages/scrabble-solver/.next/static/webpack/pages/index.fb4b50d5e70ee127.hot-update.js +171 -0
- package/packages/scrabble-solver/.next/static/webpack/webpack.fb4b50d5e70ee127.hot-update.js +18 -0
- package/packages/scrabble-solver/.next/trace +52 -52
- package/packages/scrabble-solver/package-lock.json +1533 -1363
- package/packages/scrabble-solver/package.json +20 -20
- package/packages/scrabble-solver/public/og.png +0 -0
- package/packages/scrabble-solver/src/components/Board/Board.module.scss +1 -2
- package/packages/scrabble-solver/src/components/Board/BoardPure.tsx +2 -0
- package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.module.scss +65 -55
- package/packages/scrabble-solver/src/components/Board/components/Cell/Cell.tsx +9 -0
- package/packages/scrabble-solver/src/components/Board/components/Cell/CellPure.tsx +11 -2
- package/packages/scrabble-solver/src/components/Board/hooks/useGrid.ts +6 -6
- package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +11 -1
- package/packages/scrabble-solver/src/components/Rack/Rack.tsx +16 -4
- package/packages/scrabble-solver/src/components/Rack/RackTile.tsx +10 -1
- package/packages/scrabble-solver/src/components/RemainingTiles/Character.module.scss +0 -1
- package/packages/scrabble-solver/src/components/RemainingTiles/Character.tsx +1 -0
- package/packages/scrabble-solver/src/components/Results/Results.tsx +2 -2
- package/packages/scrabble-solver/src/components/Settings/components/AutoGroupTilesSetting/AutoGroupTilesSetting.tsx +2 -2
- package/packages/scrabble-solver/src/components/Settings/components/LocaleSetting/options.ts +9 -1
- package/packages/scrabble-solver/src/components/Solver/Solver.module.scss +85 -0
- package/packages/scrabble-solver/src/components/Solver/Solver.tsx +75 -0
- package/packages/scrabble-solver/src/components/Solver/index.ts +1 -0
- package/packages/scrabble-solver/src/components/Tile/Tile.module.scss +51 -7
- package/packages/scrabble-solver/src/components/Tile/Tile.tsx +3 -0
- package/packages/scrabble-solver/src/components/Tile/TilePure.tsx +8 -1
- package/packages/scrabble-solver/src/components/index.ts +1 -0
- package/packages/scrabble-solver/src/hooks/index.ts +1 -0
- package/packages/scrabble-solver/src/hooks/useIsTouchDevice.ts +7 -0
- package/packages/scrabble-solver/src/i18n/fr.json +1 -1
- package/packages/scrabble-solver/src/icons/ExclamationSquareFill.svg +4 -0
- package/packages/scrabble-solver/src/icons/index.ts +1 -0
- package/packages/scrabble-solver/src/lib/getRemainingTilesGroups.ts +24 -26
- package/packages/scrabble-solver/src/pages/index.module.scss +1 -75
- package/packages/scrabble-solver/src/pages/index.tsx +11 -73
- package/packages/scrabble-solver/src/parameters/index.ts +2 -0
- package/packages/scrabble-solver/src/sdk/findWordDefinitions.ts +1 -1
- package/packages/scrabble-solver/src/service-worker/average.ts +9 -0
- package/packages/scrabble-solver/src/service-worker/routeSolveRequests.ts +46 -7
- package/packages/scrabble-solver/src/state/sagas.ts +19 -5
- package/packages/scrabble-solver/src/state/selectors.ts +30 -2
- package/packages/scrabble-solver/src/state/slices/boardInitialState.ts +27 -0
- package/packages/scrabble-solver/src/styles/mixins.scss +6 -1
- package/packages/scrabble-solver/src/styles/variables.scss +6 -3
- package/packages/solver/package-lock.json +2 -2
- package/packages/solver/package.json +5 -5
- package/packages/solver/src/generatePattern.ts +1 -0
- package/packages/types/build/Board.js +5 -5
- package/packages/types/build/BoardJson.d.ts +1 -1
- package/packages/types/build/Cell.js +7 -7
- package/packages/types/build/Collision.d.ts +1 -1
- package/packages/types/build/CollisionJson.d.ts +1 -1
- package/packages/types/build/Config.js +3 -3
- package/packages/types/build/Result.d.ts +1 -1
- package/packages/types/build/Result.js +8 -8
- package/packages/types/build/Tile.js +4 -4
- package/packages/types/build/WordDefinition.js +6 -6
- package/packages/types/package-lock.json +28 -0
- package/packages/types/package.json +2 -2
- package/packages/word-definitions/build/parse/parseEnglish.js +1 -1
- package/packages/word-definitions/package-lock.json +2 -2
- package/packages/word-definitions/package.json +2 -2
- package/packages/word-definitions/src/parse/__tests__/input/en-US.awe.html +2170 -323
- package/packages/word-definitions/src/parse/__tests__/input/en-US.pawn.html +2405 -349
- package/packages/word-definitions/src/parse/__tests__/input/en-US.pawnee.html +1326 -222
- package/packages/word-definitions/src/parse/__tests__/input/en-US.pean.html +1490 -201
- package/packages/word-definitions/src/parse/__tests__/input/en-US.wiz.html +1526 -272
- package/packages/word-definitions/src/parse/parseEnglish.ts +2 -1
- package/packages/word-lists/package-lock.json +23 -20
- package/packages/word-lists/package.json +2 -2
- package/packages/scrabble-solver/.next/InjectManifest.js.nft.json +0 -1
- package/packages/scrabble-solver/.next/static/chunks/368-d423e70be6c0c473.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/546-447e243fc9de2c59.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/framework-4556c45dd113b893.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/main-a75cf611e061d8f8.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/404-932294135c3206dd.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_app-3f5508a5f544d9eb.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/_error-a4ba2246ff8fb532.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/pages/index-8af7a9d7a2cd98a7.js +0 -1
- package/packages/scrabble-solver/.next/static/chunks/webpack-5752944655d749a0.js +0 -1
- package/packages/scrabble-solver/.next/static/css/6b1833fd19d3a74a.css +0 -1
- package/packages/scrabble-solver/.next/static/css/a6154e4ca046ca13.css +0 -1
- package/packages/scrabble-solver/.next/static/css/bad53af6f8616677.css +0 -1
- package/packages/scrabble-solver/.next/static/vscqn7BEtAxJteWSwNnas/_buildManifest.js +0 -1
|
@@ -3,7 +3,7 @@ import { Locale, WordDefinition, WordDefinitionJson } from '@scrabble-solver/typ
|
|
|
3
3
|
import fetchJson from './fetchJson';
|
|
4
4
|
|
|
5
5
|
const findWordDefinitions = async (locale: Locale, word: string): Promise<WordDefinition[]> => {
|
|
6
|
-
const json = await fetchJson<WordDefinitionJson[]>(`/api/dictionary/${locale}/${word}`);
|
|
6
|
+
const json = await fetchJson<WordDefinitionJson[]>(`/api/dictionary/${locale}/${encodeURIComponent(word)}`);
|
|
7
7
|
return json.map(WordDefinition.fromJson);
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { Trie } from '@kamilmielnik/trie';
|
|
1
2
|
import { getConfig } from '@scrabble-solver/configs';
|
|
2
3
|
import { BLANK } from '@scrabble-solver/constants';
|
|
3
4
|
import { solve } from '@scrabble-solver/solver';
|
|
4
5
|
import { Board, Locale, Tile } from '@scrabble-solver/types';
|
|
5
6
|
import { registerRoute } from 'workbox-routing';
|
|
6
7
|
|
|
8
|
+
import average from './average';
|
|
7
9
|
import { revalidateDictionary } from './dictionaries';
|
|
8
10
|
import getTrie from './getTrie';
|
|
9
11
|
|
|
@@ -11,24 +13,61 @@ const headers = {
|
|
|
11
13
|
'Content-Type': 'application/json; charset=utf-8',
|
|
12
14
|
};
|
|
13
15
|
|
|
16
|
+
const MIN_MEASUREMENTS = 5;
|
|
17
|
+
const localDurations: number[] = [];
|
|
18
|
+
const serverDurations: number[] = [];
|
|
19
|
+
|
|
20
|
+
const isSlowDevice = (): boolean | undefined => {
|
|
21
|
+
if (localDurations.length < MIN_MEASUREMENTS || serverDurations.length < MIN_MEASUREMENTS) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const count = Math.min(localDurations.length, serverDurations.length);
|
|
26
|
+
return average(localDurations.slice(0, count)) > average(serverDurations.slice(0, count));
|
|
27
|
+
};
|
|
28
|
+
|
|
14
29
|
const routeSolveRequests = () => {
|
|
15
30
|
registerRoute(
|
|
16
31
|
({ url }) => url.origin === location.origin && url.pathname === '/api/solve',
|
|
17
32
|
async ({ request }) => {
|
|
18
33
|
const { board, characters, configId, locale } = await request.clone().json();
|
|
34
|
+
|
|
35
|
+
const solveLocal = async (trie: Trie) => {
|
|
36
|
+
const config = getConfig(configId)[locale as Locale];
|
|
37
|
+
const tiles = characters.map((character: string) => new Tile({ character, isBlank: character === BLANK }));
|
|
38
|
+
const resultsJson = solve(trie, config, Board.fromJson(board), tiles);
|
|
39
|
+
const json = JSON.stringify(resultsJson);
|
|
40
|
+
return new Response(json, { headers });
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const solveServer = () => fetch(request);
|
|
44
|
+
|
|
19
45
|
const trie = await getTrie(locale);
|
|
20
46
|
|
|
21
|
-
if (
|
|
22
|
-
const response = await
|
|
47
|
+
if (trie && typeof isSlowDevice() === 'undefined') {
|
|
48
|
+
const response = await Promise.race([
|
|
49
|
+
(async () => {
|
|
50
|
+
const start = Date.now();
|
|
51
|
+
const result = await solveLocal(trie);
|
|
52
|
+
localDurations.push(Date.now() - start);
|
|
53
|
+
return result;
|
|
54
|
+
})(),
|
|
55
|
+
(async () => {
|
|
56
|
+
const start = Date.now();
|
|
57
|
+
const result = await solveServer();
|
|
58
|
+
serverDurations.push(Date.now() - start);
|
|
59
|
+
return result;
|
|
60
|
+
})(),
|
|
61
|
+
]);
|
|
62
|
+
|
|
23
63
|
revalidateDictionary(locale);
|
|
24
64
|
return response;
|
|
25
65
|
}
|
|
26
66
|
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return new Response(json, { headers });
|
|
67
|
+
const handleSolve = trie && !isSlowDevice() ? () => solveLocal(trie) : () => solveServer();
|
|
68
|
+
const response = await handleSolve();
|
|
69
|
+
revalidateDictionary(locale);
|
|
70
|
+
return response;
|
|
32
71
|
},
|
|
33
72
|
'POST',
|
|
34
73
|
);
|
|
@@ -7,13 +7,13 @@ import { findWordDefinitions, solve, verify, visit } from 'sdk';
|
|
|
7
7
|
|
|
8
8
|
import { initialize, reset } from './actions';
|
|
9
9
|
import {
|
|
10
|
-
selectAutoGroupTiles,
|
|
11
10
|
selectBoard,
|
|
12
11
|
selectCellIsFiltered,
|
|
13
12
|
selectCharacters,
|
|
14
13
|
selectConfig,
|
|
15
14
|
selectDictionary,
|
|
16
15
|
selectLocale,
|
|
16
|
+
selectLocaleAutoGroupTiles,
|
|
17
17
|
} from './selectors';
|
|
18
18
|
import {
|
|
19
19
|
boardSlice,
|
|
@@ -65,7 +65,7 @@ function* onRackValueChange(): AnyGenerator {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function* onApplyResult({ payload: result }: PayloadAction<Result>): AnyGenerator {
|
|
68
|
-
const autoGroupTiles = yield select(
|
|
68
|
+
const autoGroupTiles = yield select(selectLocaleAutoGroupTiles);
|
|
69
69
|
yield put(boardSlice.actions.applyResult(result));
|
|
70
70
|
yield put(cellFilterSlice.actions.reset());
|
|
71
71
|
yield put(rackSlice.actions.removeTiles(result.tiles));
|
|
@@ -74,8 +74,15 @@ function* onApplyResult({ payload: result }: PayloadAction<Result>): AnyGenerato
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function* onConfigIdChange(): AnyGenerator {
|
|
77
|
+
const characters = yield select(selectCharacters);
|
|
78
|
+
|
|
79
|
+
if (characters.length > 0) {
|
|
80
|
+
yield put(solveSlice.actions.submit());
|
|
81
|
+
} else {
|
|
82
|
+
yield put(resultsSlice.actions.reset());
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
yield put(resultsSlice.actions.reset());
|
|
78
|
-
yield put(solveSlice.actions.submit());
|
|
79
86
|
yield put(verifySlice.actions.submit());
|
|
80
87
|
yield* ensureProperTilesCount();
|
|
81
88
|
}
|
|
@@ -112,9 +119,16 @@ function* onReset(): AnyGenerator {
|
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
function* onLocaleChange(): AnyGenerator {
|
|
122
|
+
const characters = yield select(selectCharacters);
|
|
123
|
+
|
|
124
|
+
if (characters.length > 0) {
|
|
125
|
+
yield put(solveSlice.actions.submit());
|
|
126
|
+
} else {
|
|
127
|
+
yield put(resultsSlice.actions.reset());
|
|
128
|
+
}
|
|
129
|
+
|
|
115
130
|
yield put(dictionarySlice.actions.reset());
|
|
116
131
|
yield put(resultsSlice.actions.changeResultCandidate(null));
|
|
117
|
-
yield put(solveSlice.actions.submit());
|
|
118
132
|
yield put(verifySlice.actions.submit());
|
|
119
133
|
}
|
|
120
134
|
|
|
@@ -181,7 +195,7 @@ function* ensureProperTilesCount(): AnyGenerator {
|
|
|
181
195
|
} else if (config.maximumCharactersCount < characters.length) {
|
|
182
196
|
const nonNulls = characters.filter(Boolean).slice(0, config.maximumCharactersCount);
|
|
183
197
|
const differenceCount = Math.abs(config.maximumCharactersCount - nonNulls.length);
|
|
184
|
-
const autoGroupTiles = yield select(
|
|
198
|
+
const autoGroupTiles = yield select(selectLocaleAutoGroupTiles);
|
|
185
199
|
yield put(rackSlice.actions.init([...nonNulls, ...Array(differenceCount).fill(null)]));
|
|
186
200
|
yield put(rackSlice.actions.groupTiles(autoGroupTiles));
|
|
187
201
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
2
|
import { getLocaleConfig } from '@scrabble-solver/configs';
|
|
3
|
+
import { BLANK } from '@scrabble-solver/constants';
|
|
3
4
|
import { Cell, Config, isError, Result, Tile } from '@scrabble-solver/types';
|
|
4
5
|
|
|
5
|
-
import i18n from 'i18n';
|
|
6
|
+
import i18n, { LOCALE_FEATURES } from 'i18n';
|
|
6
7
|
import { findCell, getRemainingTiles, getRemainingTilesGroups, sortResults, unorderedArraysEqual } from 'lib';
|
|
7
8
|
import { Translations } from 'types';
|
|
8
9
|
|
|
@@ -38,9 +39,17 @@ export const selectDictionaryError = createSelector([selectDictionaryRoot], (dic
|
|
|
38
39
|
return isError(dictionary.error) ? dictionary.error : undefined;
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
export const selectLocale = createSelector([selectSettingsRoot], (settings) => settings.locale);
|
|
43
|
+
|
|
41
44
|
export const selectAutoGroupTiles = createSelector([selectSettingsRoot], (settings) => settings.autoGroupTiles);
|
|
42
45
|
|
|
43
|
-
export const
|
|
46
|
+
export const selectLocaleAutoGroupTiles = createSelector([selectLocale, selectSettingsRoot], (locale, settings) => {
|
|
47
|
+
if (LOCALE_FEATURES[locale].direction === 'ltr' || settings.autoGroupTiles === null) {
|
|
48
|
+
return settings.autoGroupTiles;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return settings.autoGroupTiles === 'left' ? 'right' : 'left';
|
|
52
|
+
});
|
|
44
53
|
|
|
45
54
|
export const selectBoard = selectBoardRoot;
|
|
46
55
|
|
|
@@ -54,6 +63,14 @@ export const selectCellIsFiltered = createSelector([selectCellFilter, selectPoin
|
|
|
54
63
|
return cellFilter.some((cell) => cell.x === x && cell.y === y);
|
|
55
64
|
});
|
|
56
65
|
|
|
66
|
+
export const selectCellIsValid = createSelector([selectConfig, selectCell], (config, cell) => {
|
|
67
|
+
if (!cell.hasTile()) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return config.tiles.some((tile) => tile.character === cell.tile.character);
|
|
72
|
+
});
|
|
73
|
+
|
|
57
74
|
export const selectResults = createSelector([selectResultsRoot], (results) => results.results);
|
|
58
75
|
|
|
59
76
|
export const selectResultsQuery = createSelector([selectResultsRoot], (results) => results.query);
|
|
@@ -132,6 +149,17 @@ export const selectCharacterPoints = createSelector(
|
|
|
132
149
|
},
|
|
133
150
|
);
|
|
134
151
|
|
|
152
|
+
export const selectCharacterIsValid = createSelector(
|
|
153
|
+
[selectConfig, selectCharacter],
|
|
154
|
+
(config: Config, character: string | null) => {
|
|
155
|
+
if (character === null || character === BLANK) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return config.tiles.some((tile) => tile.character === character);
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
|
|
135
163
|
export const selectTilePoints = createSelector([selectConfig, selectTile], (config: Config, tile: Tile | null) => {
|
|
136
164
|
return config.getTilePoints(tile);
|
|
137
165
|
});
|
|
@@ -7,4 +7,31 @@ const { configId, locale } = settingsInitialState;
|
|
|
7
7
|
const { boardHeight, boardWidth } = getLocaleConfig(configId, locale);
|
|
8
8
|
const boardInitialState: Board = Board.create(boardWidth, boardHeight);
|
|
9
9
|
|
|
10
|
+
// const createOxyphenbutazone = () => {
|
|
11
|
+
// // Tiles: oypbaze
|
|
12
|
+
|
|
13
|
+
// const board = Board.fromStringArray([
|
|
14
|
+
// ' x hen ut on ',
|
|
15
|
+
// 'puer or amas j',
|
|
16
|
+
// 'a led a er a',
|
|
17
|
+
// 'c ki i elf c',
|
|
18
|
+
// 'i snot n is u',
|
|
19
|
+
// 'f t o w do l',
|
|
20
|
+
// 'y e moa er a',
|
|
21
|
+
// 'i r solar t',
|
|
22
|
+
// 'n v h t i',
|
|
23
|
+
// 'g i i bitten',
|
|
24
|
+
// ' e n v g',
|
|
25
|
+
// ' w g e ',
|
|
26
|
+
// ' e ',
|
|
27
|
+
// ' d ',
|
|
28
|
+
// ' ',
|
|
29
|
+
// ]);
|
|
30
|
+
|
|
31
|
+
// board.rows[4][3].tile.isBlank = true;
|
|
32
|
+
// board.rows[9][11].tile.isBlank = true;
|
|
33
|
+
|
|
34
|
+
// return board;
|
|
35
|
+
// };
|
|
36
|
+
|
|
10
37
|
export default boardInitialState;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@mixin tablet
|
|
1
|
+
@mixin tablet {
|
|
2
2
|
@media (max-width: 1024px) {
|
|
3
3
|
@content;
|
|
4
4
|
}
|
|
@@ -73,3 +73,8 @@
|
|
|
73
73
|
font-size: var(--font--size--s);
|
|
74
74
|
font-family: var(--font--family);
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
@mixin text-stroke($color, $size: 1px) {
|
|
78
|
+
text-shadow: $size 0 $color, (-$size) 0 $color, 0 $size $color, 0 (-$size) $color, (-$size) (-$size) $color,
|
|
79
|
+
(-$size) $size $color, $size (-$size) $color, $size $size $color;
|
|
80
|
+
}
|
|
@@ -2,6 +2,7 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
4
|
--border--color: #cdcdcd;
|
|
5
|
+
--border--color--light: #d9d9d9;
|
|
5
6
|
--border--radius: 5px;
|
|
6
7
|
--border--width: 1px;
|
|
7
8
|
--border: var(--border--width) solid var(--border--color);
|
|
@@ -41,13 +42,15 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
|
|
|
41
42
|
--color--blue: #c7d8f9;
|
|
42
43
|
--color--blue--light: #dde4f6;
|
|
43
44
|
--color--light-blue: #7bb5e5;
|
|
44
|
-
--color--light-blue--light: #
|
|
45
|
+
--color--light-blue--light: #b8d5ed;
|
|
45
46
|
--color--dark-blue: #1868ad;
|
|
46
|
-
--color--dark-blue--light: #
|
|
47
|
+
--color--dark-blue--light: #86aed1;
|
|
47
48
|
--color--red: #f7c2aa;
|
|
48
49
|
--color--red--light: #fbe0d4;
|
|
49
50
|
--color--violet: #78387f;
|
|
50
|
-
--color--violet--light: #
|
|
51
|
+
--color--violet--light: #b284b8;
|
|
52
|
+
--color--orange: #fbc997;
|
|
53
|
+
--color--pink: #f19393;
|
|
51
54
|
|
|
52
55
|
--font--family: 'Open Sans', sans-serif;
|
|
53
56
|
--font--family--title: 'Lato', sans-serif;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/solver",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@scrabble-solver/solver",
|
|
9
|
-
"version": "2.10.
|
|
9
|
+
"version": "2.10.2",
|
|
10
10
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@kamilmielnik/trie": "^2.0.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/solver",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"description": "Scrabble Solver 2 - Solver",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@kamilmielnik/trie": "^2.0.1",
|
|
28
|
-
"@scrabble-solver/types": "^2.10.
|
|
28
|
+
"@scrabble-solver/types": "^2.10.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@scrabble-solver/configs": "^2.10.
|
|
32
|
-
"@scrabble-solver/constants": "^2.10.
|
|
33
|
-
"@scrabble-solver/dictionaries": "^2.10.
|
|
31
|
+
"@scrabble-solver/configs": "^2.10.2",
|
|
32
|
+
"@scrabble-solver/constants": "^2.10.2",
|
|
33
|
+
"@scrabble-solver/dictionaries": "^2.10.2"
|
|
34
34
|
},
|
|
35
35
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
36
36
|
}
|
|
@@ -12,6 +12,7 @@ const generatePattern = <P extends Pattern>({
|
|
|
12
12
|
board: Board;
|
|
13
13
|
cells: Cell[];
|
|
14
14
|
config: Config;
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
15
16
|
PatternModel: new (board: Board, cells: Cell[]) => P;
|
|
16
17
|
}): P[] => {
|
|
17
18
|
const startIndices = generateStartIndices(cells);
|
|
@@ -7,11 +7,6 @@ const constants_1 = require("@scrabble-solver/constants");
|
|
|
7
7
|
const Cell_1 = __importDefault(require("./Cell"));
|
|
8
8
|
const Tile_1 = __importDefault(require("./Tile"));
|
|
9
9
|
class Board {
|
|
10
|
-
constructor({ rows }) {
|
|
11
|
-
this.rows = rows;
|
|
12
|
-
this.columnsCount = rows[0].length;
|
|
13
|
-
this.rowsCount = rows.length;
|
|
14
|
-
}
|
|
15
10
|
static create(width, height) {
|
|
16
11
|
return Board.fromStringArray(Array(height).fill(Array(width).fill(' ').join('')));
|
|
17
12
|
}
|
|
@@ -30,6 +25,11 @@ class Board {
|
|
|
30
25
|
}))),
|
|
31
26
|
});
|
|
32
27
|
}
|
|
28
|
+
constructor({ rows }) {
|
|
29
|
+
this.rows = rows;
|
|
30
|
+
this.columnsCount = rows[0].length;
|
|
31
|
+
this.rowsCount = rows.length;
|
|
32
|
+
}
|
|
33
33
|
get center() {
|
|
34
34
|
const x = Math.floor(this.columnsCount / 2);
|
|
35
35
|
const y = Math.floor(this.rowsCount / 2);
|
|
@@ -5,13 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const Tile_1 = __importDefault(require("./Tile"));
|
|
7
7
|
class Cell {
|
|
8
|
-
// eslint-disable-next-line no-undef
|
|
9
|
-
constructor({ isEmpty = true, tile = Tile_1.default.Null, x, y }) {
|
|
10
|
-
this.isEmpty = isEmpty;
|
|
11
|
-
this.tile = tile;
|
|
12
|
-
this.x = x;
|
|
13
|
-
this.y = y;
|
|
14
|
-
}
|
|
15
8
|
static fromJson(json) {
|
|
16
9
|
return new Cell({
|
|
17
10
|
isEmpty: json.isEmpty,
|
|
@@ -20,6 +13,13 @@ class Cell {
|
|
|
20
13
|
y: json.y,
|
|
21
14
|
});
|
|
22
15
|
}
|
|
16
|
+
// eslint-disable-next-line no-undef
|
|
17
|
+
constructor({ isEmpty = true, tile = Tile_1.default.Null, x, y }) {
|
|
18
|
+
this.isEmpty = isEmpty;
|
|
19
|
+
this.tile = tile;
|
|
20
|
+
this.x = x;
|
|
21
|
+
this.y = y;
|
|
22
|
+
}
|
|
23
23
|
clone() {
|
|
24
24
|
return new Cell({
|
|
25
25
|
isEmpty: this.isEmpty,
|
|
@@ -7,14 +7,14 @@ const constants_1 = require("@scrabble-solver/constants");
|
|
|
7
7
|
const CharacterBonus_1 = __importDefault(require("./CharacterBonus"));
|
|
8
8
|
const WordBonus_1 = __importDefault(require("./WordBonus"));
|
|
9
9
|
class Config {
|
|
10
|
+
static fromJson(json) {
|
|
11
|
+
return new Config(json);
|
|
12
|
+
}
|
|
10
13
|
constructor(config) {
|
|
11
14
|
this.bonuses = getBonuses(config);
|
|
12
15
|
this.config = config;
|
|
13
16
|
this.pointsMap = getPointsMap(this.config);
|
|
14
17
|
}
|
|
15
|
-
static fromJson(json) {
|
|
16
|
-
return new Config(json);
|
|
17
|
-
}
|
|
18
18
|
get allTilesBonusScore() {
|
|
19
19
|
return this.config.allTilesBonusScore;
|
|
20
20
|
}
|
|
@@ -6,6 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const constants_1 = require("@scrabble-solver/constants");
|
|
7
7
|
const Cell_1 = __importDefault(require("./Cell"));
|
|
8
8
|
class Result {
|
|
9
|
+
static fromJson(json) {
|
|
10
|
+
return new Result({
|
|
11
|
+
id: json.id,
|
|
12
|
+
cells: json.cells.map(Cell_1.default.fromJson),
|
|
13
|
+
collisions: json.collisions.map((collision) => collision.map(Cell_1.default.fromJson)),
|
|
14
|
+
points: json.points,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
9
17
|
constructor({ cells, id, collisions, points, }) {
|
|
10
18
|
const tiles = getTiles(cells);
|
|
11
19
|
this.blanksCount = getBlanks(tiles).length;
|
|
@@ -23,14 +31,6 @@ class Result {
|
|
|
23
31
|
this.words = getWords(cells, collisions);
|
|
24
32
|
this.wordsCount = 1 + this.collisions.length;
|
|
25
33
|
}
|
|
26
|
-
static fromJson(json) {
|
|
27
|
-
return new Result({
|
|
28
|
-
id: json.id,
|
|
29
|
-
cells: json.cells.map(Cell_1.default.fromJson),
|
|
30
|
-
collisions: json.collisions.map((collision) => collision.map(Cell_1.default.fromJson)),
|
|
31
|
-
points: json.points,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
34
|
toJson() {
|
|
35
35
|
return {
|
|
36
36
|
cells: this.cells.map((cell) => cell.toJson()),
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const constants_1 = require("@scrabble-solver/constants");
|
|
4
4
|
class Tile {
|
|
5
|
-
constructor({ character, isBlank = false }) {
|
|
6
|
-
this.character = character;
|
|
7
|
-
this.isBlank = isBlank;
|
|
8
|
-
}
|
|
9
5
|
static fromJson(json) {
|
|
10
6
|
if (!json) {
|
|
11
7
|
return Tile.Null;
|
|
@@ -15,6 +11,10 @@ class Tile {
|
|
|
15
11
|
isBlank: json.isBlank,
|
|
16
12
|
});
|
|
17
13
|
}
|
|
14
|
+
constructor({ character, isBlank = false }) {
|
|
15
|
+
this.character = character;
|
|
16
|
+
this.isBlank = isBlank;
|
|
17
|
+
}
|
|
18
18
|
clone() {
|
|
19
19
|
return new Tile({
|
|
20
20
|
character: this.character,
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
class WordDefinition {
|
|
4
|
-
constructor({ definitions, exists, isAllowed, word }) {
|
|
5
|
-
this.definitions = definitions;
|
|
6
|
-
this.exists = exists;
|
|
7
|
-
this.isAllowed = isAllowed;
|
|
8
|
-
this.word = word;
|
|
9
|
-
}
|
|
10
4
|
static fromJson(json) {
|
|
11
5
|
if (!json) {
|
|
12
6
|
return WordDefinition.Null;
|
|
@@ -18,6 +12,12 @@ class WordDefinition {
|
|
|
18
12
|
word: json.word,
|
|
19
13
|
});
|
|
20
14
|
}
|
|
15
|
+
constructor({ definitions, exists, isAllowed, word }) {
|
|
16
|
+
this.definitions = definitions;
|
|
17
|
+
this.exists = exists;
|
|
18
|
+
this.isAllowed = isAllowed;
|
|
19
|
+
this.word = word;
|
|
20
|
+
}
|
|
21
21
|
toJson() {
|
|
22
22
|
return {
|
|
23
23
|
definitions: this.definitions,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scrabble-solver/types",
|
|
3
|
+
"version": "2.10.2",
|
|
4
|
+
"lockfileVersion": 2,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "@scrabble-solver/types",
|
|
9
|
+
"version": "2.10.2",
|
|
10
|
+
"license": "CC-BY-NC-ND-4.0",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@scrabble-solver/constants": "^2.10.2"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"node_modules/@scrabble-solver/constants": {
|
|
16
|
+
"version": "2.10.1",
|
|
17
|
+
"resolved": "https://registry.npmjs.org/@scrabble-solver/constants/-/constants-2.10.1.tgz",
|
|
18
|
+
"integrity": "sha512-XrLcJQREt1OHHA1VY+/8mS9avJCcS0jaXKmUABxQCPpBOZMD39G4E/0ebgwp4uNjxogIYZccRQXG2olYSZukwA=="
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@scrabble-solver/constants": {
|
|
23
|
+
"version": "2.10.1",
|
|
24
|
+
"resolved": "https://registry.npmjs.org/@scrabble-solver/constants/-/constants-2.10.1.tgz",
|
|
25
|
+
"integrity": "sha512-XrLcJQREt1OHHA1VY+/8mS9avJCcS0jaXKmUABxQCPpBOZMD39G4E/0ebgwp4uNjxogIYZccRQXG2olYSZukwA=="
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/types",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"description": "Scrabble Solver 2 - Types",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"clean:force": "npm run clean && rimraf package-lock.json"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@scrabble-solver/constants": "^2.10.
|
|
27
|
+
"@scrabble-solver/constants": "^2.10.2"
|
|
28
28
|
},
|
|
29
29
|
"gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
|
|
30
30
|
}
|
|
@@ -8,7 +8,7 @@ const parseEnglish = (html) => {
|
|
|
8
8
|
const $ = (0, cheerio_1.load)(html);
|
|
9
9
|
$('strong.mw_t_bc').replaceWith(', ');
|
|
10
10
|
$('.text-lowercase').remove();
|
|
11
|
-
$('
|
|
11
|
+
$('.sub-content-thread').remove();
|
|
12
12
|
const $definitions = $('[id^=dictionary-entry]').find('.dtText, .cxl-ref');
|
|
13
13
|
return {
|
|
14
14
|
definitions: Array.from($definitions).map((definition) => $(definition).text().replace(/\n/g, '')),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-definitions",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@scrabble-solver/word-definitions",
|
|
9
|
-
"version": "2.10.
|
|
9
|
+
"version": "2.10.2",
|
|
10
10
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"cheerio": "^1.0.0-rc.12",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrabble-solver/word-definitions",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
4
4
|
"description": "Scrabble Solver 2 - Word definitions",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"clean": "rimraf build/ node_modules/ package-lock.json"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scrabble-solver/types": "^2.10.
|
|
26
|
+
"@scrabble-solver/types": "^2.10.2",
|
|
27
27
|
"cheerio": "^1.0.0-rc.12",
|
|
28
28
|
"follow-redirects": "^1.15.2",
|
|
29
29
|
"striptags": "^3.2.0"
|