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.
Files changed (190) hide show
  1. package/.eslintrc.prettier-only.js +1 -1
  2. package/.prettierignore +3 -0
  3. package/.prettierrc +3 -3
  4. package/babel.config.js +1 -1
  5. package/lerna.json +1 -1
  6. package/package.json +6 -6
  7. package/packages/configs/package.json +3 -3
  8. package/packages/constants/package.json +1 -1
  9. package/packages/dictionaries/package-lock.json +2 -2
  10. package/packages/dictionaries/package.json +4 -4
  11. package/packages/logger/package-lock.json +2 -2
  12. package/packages/logger/package.json +1 -1
  13. package/packages/scrabble-solver/.next/BUILD_ID +1 -1
  14. package/packages/scrabble-solver/.next/build-manifest.json +10 -10
  15. package/packages/scrabble-solver/.next/cache/.tsbuildinfo +1 -1
  16. package/packages/scrabble-solver/.next/cache/eslint/.cache_8dgz12 +1 -1
  17. package/packages/scrabble-solver/.next/cache/next-server.js.nft.json +1 -1
  18. package/packages/scrabble-solver/.next/cache/webpack/client-production/0.pack +0 -0
  19. package/packages/scrabble-solver/.next/cache/webpack/client-production/index.pack +0 -0
  20. package/packages/scrabble-solver/.next/cache/webpack/server-production/0.pack +0 -0
  21. package/packages/scrabble-solver/.next/cache/webpack/server-production/index.pack +0 -0
  22. package/packages/scrabble-solver/.next/next-server.js.nft.json +1 -1
  23. package/packages/scrabble-solver/.next/prerender-manifest.json +1 -1
  24. package/packages/scrabble-solver/.next/routes-manifest.json +1 -1
  25. package/packages/scrabble-solver/.next/server/chunks/413.js +179 -44
  26. package/packages/scrabble-solver/.next/server/chunks/44.js +802 -0
  27. package/packages/scrabble-solver/.next/server/chunks/515.js +359 -95
  28. package/packages/scrabble-solver/.next/server/chunks/911.js +53 -23
  29. package/packages/scrabble-solver/.next/server/middleware-build-manifest.js +1 -1
  30. package/packages/scrabble-solver/.next/server/pages/404.html +2 -2
  31. package/packages/scrabble-solver/.next/server/pages/404.js.nft.json +1 -1
  32. package/packages/scrabble-solver/.next/server/pages/500.html +2 -2
  33. package/packages/scrabble-solver/.next/server/pages/_app.js.nft.json +1 -1
  34. package/packages/scrabble-solver/.next/server/pages/_error.js.nft.json +1 -1
  35. package/packages/scrabble-solver/.next/server/pages/api/solve.js +193 -927
  36. package/packages/scrabble-solver/.next/server/pages/api/solve.js.nft.json +1 -1
  37. package/packages/scrabble-solver/.next/server/pages/api/verify.js +217 -0
  38. package/packages/scrabble-solver/.next/server/pages/api/verify.js.nft.json +1 -0
  39. package/packages/scrabble-solver/.next/server/pages/index.html +3 -3
  40. package/packages/scrabble-solver/.next/server/pages/index.js +7 -1
  41. package/packages/scrabble-solver/.next/server/pages/index.js.nft.json +1 -1
  42. package/packages/scrabble-solver/.next/server/pages/index.json +1 -1
  43. package/packages/scrabble-solver/.next/server/pages-manifest.json +1 -0
  44. package/packages/scrabble-solver/.next/static/chunks/317-a33dd38e9b9a17ed.js +1 -0
  45. package/packages/scrabble-solver/.next/static/chunks/pages/{404-8eb3ba4f0ba17e08.js → 404-90c624da3c83fd17.js} +1 -1
  46. package/packages/scrabble-solver/.next/static/chunks/pages/_app-f8f360878e1c2aff.js +1 -0
  47. package/packages/scrabble-solver/.next/static/chunks/pages/index-ecea697d3e5d8a6f.js +1 -0
  48. package/packages/scrabble-solver/.next/static/css/64dc2ce1811912f1.css +1 -0
  49. package/packages/scrabble-solver/.next/static/css/{cdbc9e0afcff5473.css → ad2a08918868cad8.css} +1 -1
  50. package/packages/scrabble-solver/.next/static/yCxjzzYpw5JjJE53PO_s6/_buildManifest.js +1 -0
  51. package/packages/scrabble-solver/.next/static/{z3J3qmq1nazbDv_ENIkCo → yCxjzzYpw5JjJE53PO_s6}/_ssgManifest.js +0 -0
  52. package/packages/scrabble-solver/.next/trace +42 -41
  53. package/packages/scrabble-solver/package-lock.json +2 -2
  54. package/packages/scrabble-solver/package.json +8 -8
  55. package/packages/scrabble-solver/src/components/Badge/Badge.module.scss +13 -0
  56. package/packages/scrabble-solver/src/components/Badge/Badge.tsx +15 -0
  57. package/packages/scrabble-solver/src/components/Badge/index.ts +1 -0
  58. package/packages/scrabble-solver/src/components/NavButtons/NavButtons.tsx +33 -14
  59. package/packages/scrabble-solver/src/components/RemainingTiles/RemainingTiles.module.scss +8 -7
  60. package/packages/scrabble-solver/src/components/RemainingTiles/RemainingTiles.tsx +13 -4
  61. package/packages/scrabble-solver/src/components/Sidebar/Sidebar.tsx +2 -2
  62. package/packages/scrabble-solver/src/components/Sidebar/components/Section/Section.module.scss +0 -1
  63. package/packages/scrabble-solver/src/components/Sidebar/components/Section/Section.tsx +1 -1
  64. package/packages/scrabble-solver/src/components/SquareButton/SquareButton.module.scss +5 -0
  65. package/packages/scrabble-solver/src/components/Words/Words.module.scss +35 -0
  66. package/packages/scrabble-solver/src/components/Words/Words.tsx +57 -0
  67. package/packages/scrabble-solver/src/components/Words/index.ts +1 -0
  68. package/packages/scrabble-solver/src/components/index.ts +2 -0
  69. package/packages/scrabble-solver/src/i18n/de.json +4 -1
  70. package/packages/scrabble-solver/src/i18n/en.json +4 -1
  71. package/packages/scrabble-solver/src/i18n/es.json +4 -1
  72. package/packages/scrabble-solver/src/i18n/fr.json +4 -1
  73. package/packages/scrabble-solver/src/i18n/pl.json +4 -1
  74. package/packages/scrabble-solver/src/icons/BookHalf.svg +4 -0
  75. package/packages/scrabble-solver/src/icons/Check.svg +4 -0
  76. package/packages/scrabble-solver/src/icons/Cross.svg +2 -2
  77. package/packages/scrabble-solver/src/icons/CrossFill.svg +4 -0
  78. package/packages/scrabble-solver/src/icons/index.ts +3 -0
  79. package/packages/scrabble-solver/src/pages/api/solve.ts +2 -3
  80. package/packages/scrabble-solver/src/pages/api/verify.ts +71 -0
  81. package/packages/scrabble-solver/src/pages/index.tsx +5 -0
  82. package/packages/scrabble-solver/src/sdk/index.ts +1 -0
  83. package/packages/scrabble-solver/src/sdk/verify.ts +24 -0
  84. package/packages/scrabble-solver/src/state/rootReducer.ts +2 -0
  85. package/packages/scrabble-solver/src/state/sagas.ts +33 -6
  86. package/packages/scrabble-solver/src/state/selectors.ts +8 -0
  87. package/packages/scrabble-solver/src/state/slices/index.ts +2 -0
  88. package/packages/scrabble-solver/src/state/slices/verifyInitialState.ts +12 -0
  89. package/packages/scrabble-solver/src/state/slices/verifySlice.ts +31 -0
  90. package/packages/scrabble-solver/src/styles/variables.scss +2 -1
  91. package/packages/scrabble-solver/src/types/index.ts +4 -1
  92. package/packages/solver/build/fillPattern.d.ts +5 -0
  93. package/packages/solver/build/fillPattern.js +52 -0
  94. package/packages/solver/build/generateEndIndices.d.ts +3 -0
  95. package/packages/solver/build/generateEndIndices.js +9 -0
  96. package/packages/solver/build/generateHorizontalPatterns.d.ts +3 -0
  97. package/packages/solver/build/generateHorizontalPatterns.js +18 -0
  98. package/packages/solver/build/generatePattern.d.ts +8 -0
  99. package/packages/solver/build/generatePattern.js +22 -0
  100. package/packages/solver/build/generatePatterns.d.ts +3 -0
  101. package/packages/solver/build/generatePatterns.js +13 -0
  102. package/packages/solver/build/generateStartIndices.d.ts +3 -0
  103. package/packages/solver/build/generateStartIndices.js +9 -0
  104. package/packages/solver/build/generateVectors.d.ts +6 -0
  105. package/packages/solver/build/generateVectors.js +8 -0
  106. package/packages/solver/build/generateVerticalPatterns.d.ts +3 -0
  107. package/packages/solver/build/generateVerticalPatterns.js +18 -0
  108. package/packages/solver/build/getCellsScore.d.ts +3 -0
  109. package/packages/solver/build/getCellsScore.js +16 -0
  110. package/packages/solver/build/getPatternHash.d.ts +3 -0
  111. package/packages/solver/build/getPatternHash.js +13 -0
  112. package/packages/solver/build/getPatternScore.d.ts +3 -0
  113. package/packages/solver/build/getPatternScore.js +15 -0
  114. package/packages/solver/build/getUniquePatterns.js +5 -11
  115. package/packages/solver/build/index.d.ts +1 -1
  116. package/packages/solver/build/index.js +3 -3
  117. package/packages/solver/build/solve.d.ts +4 -0
  118. package/packages/solver/build/solve.js +23 -0
  119. package/packages/solver/package-lock.json +2 -2
  120. package/packages/solver/package.json +5 -5
  121. package/packages/solver/src/fillPattern.test.ts +107 -0
  122. package/packages/solver/src/fillPattern.ts +70 -0
  123. package/packages/solver/src/generateEndIndices.test.ts +18 -0
  124. package/packages/solver/src/generateEndIndices.ts +10 -0
  125. package/packages/solver/src/generateHorizontalPatterns.test.ts +31 -0
  126. package/packages/solver/src/generateHorizontalPatterns.ts +17 -0
  127. package/packages/solver/src/generatePattern.ts +35 -0
  128. package/packages/solver/src/generatePatterns.ts +13 -0
  129. package/packages/solver/src/generateStartIndices.test.ts +14 -0
  130. package/packages/solver/src/generateStartIndices.ts +10 -0
  131. package/packages/solver/src/generateVectors.test.ts +12 -0
  132. package/packages/solver/src/generateVectors.ts +15 -0
  133. package/packages/solver/src/generateVerticalPatterns.test.ts +32 -0
  134. package/packages/solver/src/generateVerticalPatterns.ts +17 -0
  135. package/packages/solver/src/getCellsScore.ts +22 -0
  136. package/packages/solver/src/getPatternHash.test.ts +17 -0
  137. package/packages/solver/src/getPatternHash.ts +14 -0
  138. package/packages/solver/src/getPatternScore.test.ts +60 -0
  139. package/packages/solver/src/getPatternScore.ts +15 -0
  140. package/packages/solver/src/getUniquePatterns.ts +1 -10
  141. package/packages/solver/src/index.ts +1 -1
  142. package/packages/solver/src/{Solver.test.ts → solve.test.ts} +14 -13
  143. package/packages/solver/src/solve.ts +25 -0
  144. package/packages/types/build/Board.d.ts +1 -0
  145. package/packages/types/build/Board.js +17 -1
  146. package/packages/types/build/Config.js +1 -1
  147. package/packages/types/build/FinalPattern.d.ts +7 -0
  148. package/packages/types/build/FinalPattern.js +16 -0
  149. package/packages/types/build/HorizontalPattern.js +2 -5
  150. package/packages/types/build/Pattern.d.ts +1 -4
  151. package/packages/types/build/Pattern.js +2 -5
  152. package/packages/types/build/Result.js +3 -5
  153. package/packages/types/build/Tile.d.ts +2 -2
  154. package/packages/types/build/VerticalPattern.js +2 -5
  155. package/packages/types/build/index.d.ts +1 -0
  156. package/packages/types/build/index.js +3 -1
  157. package/packages/types/package.json +2 -2
  158. package/packages/types/src/Board.ts +23 -1
  159. package/packages/types/src/Config.ts +1 -1
  160. package/packages/types/src/FinalPattern.ts +16 -0
  161. package/packages/types/src/HorizontalPattern.ts +5 -5
  162. package/packages/types/src/Pattern.ts +5 -5
  163. package/packages/types/src/Result.ts +3 -5
  164. package/packages/types/src/Tile.ts +2 -2
  165. package/packages/types/src/VerticalPattern.ts +5 -5
  166. package/packages/types/src/index.ts +1 -0
  167. package/packages/word-definitions/package-lock.json +2 -2
  168. package/packages/word-definitions/package.json +2 -2
  169. package/packages/word-lists/package-lock.json +2 -2
  170. package/packages/word-lists/package.json +2 -2
  171. package/packages/scrabble-solver/.next/static/chunks/615-d258f6c528c18622.js +0 -1
  172. package/packages/scrabble-solver/.next/static/chunks/pages/_app-4a663fd3d5ca4524.js +0 -1
  173. package/packages/scrabble-solver/.next/static/chunks/pages/index-1a9826d740cc8830.js +0 -1
  174. package/packages/scrabble-solver/.next/static/css/180c6c26317ac90f.css +0 -1
  175. package/packages/scrabble-solver/.next/static/z3J3qmq1nazbDv_ENIkCo/_buildManifest.js +0 -1
  176. package/packages/solver/build/PatternsFiller.d.ts +0 -12
  177. package/packages/solver/build/PatternsFiller.js +0 -70
  178. package/packages/solver/build/PatternsGenerator.d.ts +0 -32
  179. package/packages/solver/build/PatternsGenerator.js +0 -66
  180. package/packages/solver/build/ScoresCalculator.d.ts +0 -17
  181. package/packages/solver/build/ScoresCalculator.js +0 -37
  182. package/packages/solver/build/Solver.d.ts +0 -10
  183. package/packages/solver/build/Solver.js +0 -30
  184. package/packages/solver/src/PatternsFiller.test.ts +0 -92
  185. package/packages/solver/src/PatternsFiller.ts +0 -91
  186. package/packages/solver/src/PatternsGenerator.test.ts +0 -89
  187. package/packages/solver/src/PatternsGenerator.ts +0 -103
  188. package/packages/solver/src/ScoresCalculator.test.ts +0 -70
  189. package/packages/solver/src/ScoresCalculator.ts +0 -52
  190. package/packages/solver/src/Solver.ts +0 -39
@@ -3,7 +3,7 @@ import { Result } from '@scrabble-solver/types';
3
3
  import { call, delay, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
4
4
 
5
5
  import { memoize } from 'lib';
6
- import { findWordDefinitions, solve, visit } from 'sdk';
6
+ import { findWordDefinitions, solve, verify, visit } from 'sdk';
7
7
 
8
8
  import { initialize, reset } from './actions';
9
9
  import {
@@ -23,6 +23,7 @@ import {
23
23
  resultsSlice,
24
24
  settingsSlice,
25
25
  solveSlice,
26
+ verifySlice,
26
27
  } from './slices';
27
28
 
28
29
  const SUBMIT_DELAY = 150;
@@ -43,7 +44,8 @@ export function* rootSaga(): AnyGenerator {
43
44
  yield takeLatest(dictionarySlice.actions.submit.type, onDictionarySubmit);
44
45
  yield takeLatest(initialize.type, onInitialize);
45
46
  yield takeLatest(reset.type, onReset);
46
- yield takeLatest(solveSlice.actions.submit.type, onSubmit);
47
+ yield takeLatest(solveSlice.actions.submit.type, onSolve);
48
+ yield takeLatest(verifySlice.actions.submit.type, onVerify);
47
49
  }
48
50
 
49
51
  function* onCellValueChange({ payload }: PayloadAction<{ value: string; x: number; y: number }>): AnyGenerator {
@@ -52,6 +54,8 @@ function* onCellValueChange({ payload }: PayloadAction<{ value: string; x: numbe
52
54
  if (isFiltered) {
53
55
  yield put(cellFilterSlice.actions.toggle(payload));
54
56
  }
57
+
58
+ yield put(verifySlice.actions.submit());
55
59
  }
56
60
 
57
61
  function* onApplyResult({ payload: result }: PayloadAction<Result>): AnyGenerator {
@@ -60,11 +64,13 @@ function* onApplyResult({ payload: result }: PayloadAction<Result>): AnyGenerato
60
64
  yield put(cellFilterSlice.actions.reset());
61
65
  yield put(rackSlice.actions.removeTiles(result.tiles));
62
66
  yield put(rackSlice.actions.groupTiles(autoGroupTiles));
67
+ yield put(verifySlice.actions.submit());
63
68
  }
64
69
 
65
70
  function* onConfigIdChange(): AnyGenerator {
66
71
  yield put(resultsSlice.actions.reset());
67
72
  yield put(solveSlice.actions.submit());
73
+ yield put(verifySlice.actions.submit());
68
74
  yield* ensureProperTilesCount();
69
75
  }
70
76
 
@@ -95,12 +101,14 @@ function* onReset(): AnyGenerator {
95
101
  yield put(dictionarySlice.actions.reset());
96
102
  yield put(rackSlice.actions.reset());
97
103
  yield put(resultsSlice.actions.reset());
104
+ yield put(verifySlice.actions.submit());
98
105
  }
99
106
 
100
107
  function* onLocaleChange(): AnyGenerator {
101
- yield put(solveSlice.actions.submit());
102
- yield put(resultsSlice.actions.changeResultCandidate(null));
103
108
  yield put(dictionarySlice.actions.reset());
109
+ yield put(resultsSlice.actions.changeResultCandidate(null));
110
+ yield put(solveSlice.actions.submit());
111
+ yield put(verifySlice.actions.submit());
104
112
  }
105
113
 
106
114
  function* onResultCandidateChange({ payload: result }: PayloadAction<Result | null>): AnyGenerator {
@@ -110,7 +118,7 @@ function* onResultCandidateChange({ payload: result }: PayloadAction<Result | nu
110
118
  }
111
119
  }
112
120
 
113
- function* onSubmit(): AnyGenerator {
121
+ function* onSolve(): AnyGenerator {
114
122
  const board = yield select(selectBoard);
115
123
  const { config } = yield select(selectConfig);
116
124
  const locale = yield select(selectLocale);
@@ -129,14 +137,33 @@ function* onSubmit(): AnyGenerator {
129
137
  configId: config.id,
130
138
  locale,
131
139
  });
132
- yield put(solveSlice.actions.submitSuccess({ board, characters }));
133
140
  yield put(resultsSlice.actions.changeResults(results.map(Result.fromJson)));
141
+ yield put(solveSlice.actions.submitSuccess({ board, characters }));
134
142
  } catch (error) {
135
143
  yield put(resultsSlice.actions.changeResults([]));
136
144
  yield put(solveSlice.actions.submitFailure());
137
145
  }
138
146
  }
139
147
 
148
+ function* onVerify(): AnyGenerator {
149
+ yield delay(SUBMIT_DELAY);
150
+
151
+ const board = yield select(selectBoard);
152
+ const { config } = yield select(selectConfig);
153
+ const locale = yield select(selectLocale);
154
+
155
+ try {
156
+ const { invalidWords, validWords } = yield call(verify, {
157
+ board: board.toJson(),
158
+ configId: config.id,
159
+ locale,
160
+ });
161
+ yield put(verifySlice.actions.submitSuccess({ board, invalidWords, validWords }));
162
+ } catch (error) {
163
+ yield put(verifySlice.actions.submitFailure());
164
+ }
165
+ }
166
+
140
167
  function* ensureProperTilesCount(): AnyGenerator {
141
168
  const { config } = yield select(selectConfig);
142
169
  const characters = yield select(selectCharacters);
@@ -30,6 +30,8 @@ const selectSettingsRoot = (state: RootState): RootState['settings'] => state.se
30
30
 
31
31
  const selectSolveRoot = (state: RootState): RootState['solve'] => state.solve;
32
32
 
33
+ const selectVerifyRoot = (state: RootState): RootState['verify'] => state.verify;
34
+
33
35
  export const selectDictionary = selectDictionaryRoot;
34
36
 
35
37
  export const selectAutoGroupTiles = createSelector([selectSettingsRoot], (settings) => settings.autoGroupTiles);
@@ -183,3 +185,9 @@ export const selectHasOverusedTiles = createSelector([selectRemainingTiles], (re
183
185
  });
184
186
 
185
187
  export const selectRemainingTilesGroups = createSelector([selectRemainingTiles], getRemainingTilesGroups);
188
+
189
+ export const selectVerify = selectVerifyRoot;
190
+
191
+ export const selectHasInvalidWords = createSelector([selectVerify], ({ invalidWords }) => {
192
+ return invalidWords.length > 0;
193
+ });
@@ -12,3 +12,5 @@ export { default as settingsInitialState } from './settingsInitialState';
12
12
  export { default as settingsSlice } from './settingsSlice';
13
13
  export { default as solveInitialState } from './solveInitialState';
14
14
  export { default as solveSlice } from './solveSlice';
15
+ export { default as verifyInitialState } from './verifyInitialState';
16
+ export { default as verifySlice } from './verifySlice';
@@ -0,0 +1,12 @@
1
+ import boardInitialState from './boardInitialState';
2
+
3
+ const verifyInitialState = {
4
+ isLoading: false,
5
+ lastSolvedParameters: {
6
+ board: boardInitialState,
7
+ },
8
+ invalidWords: [] as string[],
9
+ validWords: [] as string[],
10
+ };
11
+
12
+ export default verifyInitialState;
@@ -0,0 +1,31 @@
1
+ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
2
+ import { Board } from '@scrabble-solver/types';
3
+
4
+ import verifyInitialState from './verifyInitialState';
5
+
6
+ interface VerifyParameters {
7
+ board: Board;
8
+ invalidWords: string[];
9
+ validWords: string[];
10
+ }
11
+
12
+ const verifySlice = createSlice({
13
+ initialState: verifyInitialState,
14
+ name: 'verify',
15
+ reducers: {
16
+ submit: (state) => {
17
+ return { ...state, isLoading: true };
18
+ },
19
+
20
+ submitFailure: (state) => {
21
+ return { ...state, isLoading: false };
22
+ },
23
+
24
+ submitSuccess: (state, action: PayloadAction<VerifyParameters>) => {
25
+ const { board, invalidWords, validWords } = action.payload;
26
+ return { ...state, isLoading: false, lastSolvedParameters: { board }, invalidWords, validWords };
27
+ },
28
+ },
29
+ });
30
+
31
+ export default verifySlice;
@@ -26,7 +26,8 @@ $easeOutSine: cubic-bezier(0.61, 1, 0.88, 1);
26
26
  --color--background: #f4f4f4;
27
27
  --color--background--secondary: #111;
28
28
  --color--background--overlay: rgba(255, 255, 255, 0.65);
29
- --color--error: rgba(255, 0, 0, 0.75);
29
+ --color--error: #fc3d3d;
30
+ --color--success: #00a900;
30
31
  --color--focus: #{rgba(#268fff, 0.5)};
31
32
  --color--foreground: black;
32
33
  --color--foreground--secondary: #444;
@@ -80,7 +80,10 @@ export type TranslationKey =
80
80
  | 'settings.autoGroupTiles.right'
81
81
  | 'settings.autoGroupTiles.null'
82
82
  | 'settings.game'
83
- | 'settings.language';
83
+ | 'settings.language'
84
+ | 'words'
85
+ | 'words.invalid'
86
+ | 'words.valid';
84
87
 
85
88
  export type Translate = (key: TranslationKey) => string;
86
89
 
@@ -0,0 +1,5 @@
1
+ import { Trie } from '@kamilmielnik/trie';
2
+ import { Config, Pattern, Tile } from '@scrabble-solver/types';
3
+ declare const fillPattern: (trie: Trie, config: Config, pattern: Pattern, tiles: Tile[]) => Pattern[];
4
+ export declare const fillPatternRecursive: (results: Pattern[], trie: Trie, config: Config, pattern: Pattern, word: string, tiles: Tile[]) => void;
5
+ export default fillPattern;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fillPatternRecursive = void 0;
4
+ const constants_1 = require("@scrabble-solver/constants");
5
+ const types_1 = require("@scrabble-solver/types");
6
+ const fillPattern = (trie, config, pattern, tiles) => {
7
+ if (pattern.getEmptyCellsCount() > tiles.length) {
8
+ return [];
9
+ }
10
+ const results = [];
11
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, pattern.toString(), tiles);
12
+ return results;
13
+ };
14
+ const fillPatternRecursive = (
15
+ /** gets mutated when this function is called */
16
+ results, trie, config, pattern, word, tiles) => {
17
+ const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
18
+ if (indexOfFirstCellWithoutTile === -1) {
19
+ if (trie.has(word) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
20
+ results.push(new types_1.FinalPattern(pattern.clone()));
21
+ }
22
+ return;
23
+ }
24
+ for (let index = 0; index < tiles.length; ++index) {
25
+ const tile = tiles[index];
26
+ const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
27
+ pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
28
+ const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
29
+ const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
30
+ const prefix = word.substring(0, indexOfFirstEmptyLetter);
31
+ const suffix = word.substring(indexOfFirstEmptyLetter + 1);
32
+ const characters = tile.isBlank ? config.alphabet : [tile.character];
33
+ for (const character of characters) {
34
+ const newWordPrefix = prefix + character;
35
+ const newWord = newWordPrefix + suffix;
36
+ tile.character = character;
37
+ if (indexOfNextCellWithoutTile === -1) {
38
+ if (trie.has(newWord) && pattern.getCollisions().every((collision) => trie.has(collision.toString()))) {
39
+ results.push(new types_1.FinalPattern(pattern.clone()));
40
+ }
41
+ }
42
+ else if (trie.hasPrefix(newWordPrefix)) {
43
+ tiles.splice(index, 1);
44
+ (0, exports.fillPatternRecursive)(results, trie, config, pattern, newWord, tiles);
45
+ tiles.splice(index, 0, tile);
46
+ }
47
+ }
48
+ pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
49
+ }
50
+ };
51
+ exports.fillPatternRecursive = fillPatternRecursive;
52
+ exports.default = fillPattern;
@@ -0,0 +1,3 @@
1
+ import { Cell } from '@scrabble-solver/types';
2
+ declare const generateEndIndices: (cells: Cell[], startIndex: number) => number[];
3
+ export default generateEndIndices;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const generateEndIndices = (cells, startIndex) => {
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
+ exports.default = generateEndIndices;
@@ -0,0 +1,3 @@
1
+ import { Board, Config, Pattern } from '@scrabble-solver/types';
2
+ declare const generateHorizontalPatterns: (config: Config, board: Board) => Pattern[];
3
+ export default generateHorizontalPatterns;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const types_1 = require("@scrabble-solver/types");
7
+ const generatePattern_1 = __importDefault(require("./generatePattern"));
8
+ const generateVectors_1 = __importDefault(require("./generateVectors"));
9
+ const generateHorizontalPatterns = (config, board) => {
10
+ const getNthVector = (index) => board.getRow(index);
11
+ const vectorsCount = config.boardHeight;
12
+ const horizontalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
13
+ const horizontalPatterns = horizontalVectors.flatMap((cells) => {
14
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.HorizontalPattern, cells });
15
+ });
16
+ return horizontalPatterns;
17
+ };
18
+ exports.default = generateHorizontalPatterns;
@@ -0,0 +1,8 @@
1
+ import { Board, Cell, Config, Pattern } from '@scrabble-solver/types';
2
+ declare const generatePattern: <P extends Pattern>({ board, cells, config, PatternModel, }: {
3
+ board: Board;
4
+ cells: Cell[];
5
+ config: Config;
6
+ PatternModel: new (board: Board, cells: Cell[]) => P;
7
+ }) => P[];
8
+ export default generatePattern;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const generateEndIndices_1 = __importDefault(require("./generateEndIndices"));
7
+ const generateStartIndices_1 = __importDefault(require("./generateStartIndices"));
8
+ const generatePattern = ({ board, cells, config, PatternModel, }) => {
9
+ const startIndices = (0, generateStartIndices_1.default)(cells);
10
+ return startIndices.flatMap((startIndex) => {
11
+ const endIndices = (0, generateEndIndices_1.default)(cells, startIndex);
12
+ const patterns = [];
13
+ for (const endIndex of endIndices) {
14
+ const pattern = new PatternModel(board, cells.slice(startIndex, endIndex + 1));
15
+ if (pattern.canBePlaced(config)) {
16
+ patterns.push(pattern);
17
+ }
18
+ }
19
+ return patterns;
20
+ });
21
+ };
22
+ exports.default = generatePattern;
@@ -0,0 +1,3 @@
1
+ import { Board, Config, Pattern } from '@scrabble-solver/types';
2
+ declare const generatePatterns: (config: Config, board: Board) => Pattern[];
3
+ export default generatePatterns;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const generateHorizontalPatterns_1 = __importDefault(require("./generateHorizontalPatterns"));
7
+ const generateVerticalPatterns_1 = __importDefault(require("./generateVerticalPatterns"));
8
+ const generatePatterns = (config, board) => {
9
+ const horizontalPatterns = (0, generateHorizontalPatterns_1.default)(config, board);
10
+ const verticalPatterns = (0, generateVerticalPatterns_1.default)(config, board);
11
+ return horizontalPatterns.concat(verticalPatterns);
12
+ };
13
+ exports.default = generatePatterns;
@@ -0,0 +1,3 @@
1
+ import { Cell } from '@scrabble-solver/types';
2
+ declare const generateStartIndices: (cells: Cell[]) => number[];
3
+ export default generateStartIndices;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const generateStartIndices = (cells) => {
4
+ return Array(cells.length - 1)
5
+ .fill(0)
6
+ .map((_, startIndex) => startIndex)
7
+ .filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
8
+ };
9
+ exports.default = generateStartIndices;
@@ -0,0 +1,6 @@
1
+ import { Cell } from '@scrabble-solver/types';
2
+ declare const generateVectors: ({ getNthVector, vectorsCount, }: {
3
+ getNthVector: (index: number) => Cell[];
4
+ vectorsCount: number;
5
+ }) => Cell[][];
6
+ export default generateVectors;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const generateVectors = ({ getNthVector, vectorsCount, }) => {
4
+ return Array(vectorsCount)
5
+ .fill(0)
6
+ .map((_, index) => getNthVector(index));
7
+ };
8
+ exports.default = generateVectors;
@@ -0,0 +1,3 @@
1
+ import { Board, Config, Pattern } from '@scrabble-solver/types';
2
+ declare const generateVerticalPatterns: (config: Config, board: Board) => Pattern[];
3
+ export default generateVerticalPatterns;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const types_1 = require("@scrabble-solver/types");
7
+ const generatePattern_1 = __importDefault(require("./generatePattern"));
8
+ const generateVectors_1 = __importDefault(require("./generateVectors"));
9
+ const generateVerticalPatterns = (config, board) => {
10
+ const getNthVector = (index) => board.getColumn(index);
11
+ const vectorsCount = config.boardWidth;
12
+ const verticalVectors = (0, generateVectors_1.default)({ getNthVector, vectorsCount });
13
+ const verticalPatterns = verticalVectors.flatMap((cells) => {
14
+ return (0, generatePattern_1.default)({ board, config, PatternModel: types_1.VerticalPattern, cells });
15
+ });
16
+ return verticalPatterns;
17
+ };
18
+ exports.default = generateVerticalPatterns;
@@ -0,0 +1,3 @@
1
+ import { Cell, Config } from '@scrabble-solver/types';
2
+ declare const getCellsScore: (config: Config, cells: Cell[]) => number;
3
+ export default getCellsScore;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("@scrabble-solver/constants");
4
+ const getCellsScore = (config, cells) => {
5
+ const total = cells.reduce(({ multiplier, score }, cell) => {
6
+ const bonus = config.getCellBonus(cell);
7
+ const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(config, cell) ? bonus.value : constants_1.NO_BONUS;
8
+ const characterScore = cell.tile.isBlank ? config.blankScore : config.pointsMap[cell.tile.character];
9
+ return {
10
+ multiplier: multiplier * wordMultiplier,
11
+ score: score + characterScore * characterMultiplier,
12
+ };
13
+ }, { multiplier: 1, score: 0 });
14
+ return total.score * total.multiplier;
15
+ };
16
+ exports.default = getCellsScore;
@@ -0,0 +1,3 @@
1
+ import { Pattern } from '@scrabble-solver/types';
2
+ declare const getPatternHash: (pattern: Pattern) => string;
3
+ export default getPatternHash;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const getPatternHash = (pattern) => {
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
+ exports.default = getPatternHash;
@@ -0,0 +1,3 @@
1
+ import { Config, Pattern } from '@scrabble-solver/types';
2
+ declare const getPatternScore: (config: Config, pattern: Pattern) => number;
3
+ export default getPatternScore;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const getCellsScore_1 = __importDefault(require("./getCellsScore"));
7
+ const getPatternScore = (config, pattern) => {
8
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === config.maximumCharactersCount;
9
+ const bonusScore = areAllTilesUsed ? config.allTilesBonusScore : 0;
10
+ const score = pattern
11
+ .getCollisions()
12
+ .reduce((sum, collision) => sum + (0, getCellsScore_1.default)(config, collision.cells), (0, getCellsScore_1.default)(config, pattern.cells));
13
+ return score + bonusScore;
14
+ };
15
+ exports.default = getPatternScore;
@@ -1,20 +1,14 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const getPatternHash = (pattern) => {
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('-');
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
4
  };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const getPatternHash_1 = __importDefault(require("./getPatternHash"));
13
7
  const getUniquePatterns = (patterns) => {
14
8
  const hashes = new Set();
15
9
  const uniquePatterns = [];
16
10
  for (const pattern of patterns) {
17
- const hash = getPatternHash(pattern);
11
+ const hash = (0, getPatternHash_1.default)(pattern);
18
12
  if (!hashes.has(hash)) {
19
13
  hashes.add(hash);
20
14
  uniquePatterns.push(pattern);
@@ -1 +1 @@
1
- export { default } from './Solver';
1
+ export { default as solve } from './solve';
@@ -3,6 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = void 0;
7
- var Solver_1 = require("./Solver");
8
- Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(Solver_1).default; } });
6
+ exports.solve = void 0;
7
+ var solve_1 = require("./solve");
8
+ Object.defineProperty(exports, "solve", { enumerable: true, get: function () { return __importDefault(solve_1).default; } });
@@ -0,0 +1,4 @@
1
+ import { Trie } from '@kamilmielnik/trie';
2
+ import { Board, Config, Result, Tile } from '@scrabble-solver/types';
3
+ declare const solve: (trie: Trie, config: Config, board: Board, tiles: Tile[]) => Result[];
4
+ export default solve;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const types_1 = require("@scrabble-solver/types");
7
+ const fillPattern_1 = __importDefault(require("./fillPattern"));
8
+ const generatePatterns_1 = __importDefault(require("./generatePatterns"));
9
+ const getPatternScore_1 = __importDefault(require("./getPatternScore"));
10
+ const getUniquePatterns_1 = __importDefault(require("./getUniquePatterns"));
11
+ const solve = (trie, config, board, tiles) => {
12
+ const patterns = (0, generatePatterns_1.default)(config, board);
13
+ const filledPatterns = patterns.flatMap((pattern) => (0, fillPattern_1.default)(trie, config, pattern, tiles));
14
+ const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
15
+ const results = uniquePatterns.map((pattern, index) => new types_1.Result({
16
+ cells: pattern.cells,
17
+ collisions: pattern.getCollisions().map((collision) => collision.cells),
18
+ id: index,
19
+ points: (0, getPatternScore_1.default)(config, pattern),
20
+ }));
21
+ return results;
22
+ };
23
+ exports.default = solve;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.8.8",
3
+ "version": "2.8.9",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@scrabble-solver/solver",
9
- "version": "2.8.8",
9
+ "version": "2.8.9",
10
10
  "license": "CC-BY-NC-ND-4.0",
11
11
  "dependencies": {
12
12
  "@kamilmielnik/trie": "^2.0.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.8.8",
3
+ "version": "2.8.9",
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.0",
28
- "@scrabble-solver/types": "^2.8.8"
28
+ "@scrabble-solver/types": "^2.8.9"
29
29
  },
30
30
  "devDependencies": {
31
- "@scrabble-solver/configs": "^2.8.8",
32
- "@scrabble-solver/constants": "^2.8.8",
33
- "@scrabble-solver/dictionaries": "^2.8.8"
31
+ "@scrabble-solver/configs": "^2.8.9",
32
+ "@scrabble-solver/constants": "^2.8.9",
33
+ "@scrabble-solver/dictionaries": "^2.8.9"
34
34
  },
35
35
  "gitHead": "1e2d1ad49a288d4a44196d8e3336740da132c637"
36
36
  }