@scrabble-solver/solver 2.8.5 → 2.8.7

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.
@@ -9,7 +9,7 @@ class PatternsFiller {
9
9
  }
10
10
  fill(pattern, tiles) {
11
11
  const patterns = [];
12
- if (pattern.getNumberOfEmptyCells() > tiles.length) {
12
+ if (pattern.getEmptyCellsCount() > tiles.length) {
13
13
  return [];
14
14
  }
15
15
  const onPatternFound = (newPattern) => patterns.push(newPattern);
@@ -5,18 +5,18 @@ declare class PatternsGenerator {
5
5
  generate(board: Board): Pattern[];
6
6
  generateHorizontal(board: Board): HorizontalPattern[];
7
7
  generateVertical(board: Board): VerticalPattern[];
8
- generatePatterns<P extends Pattern>({ board, getNthVector, numberOfVectors, PatternModel, }: {
8
+ generatePatterns<P extends Pattern>({ board, getNthVector, vectorsCount, PatternModel, }: {
9
9
  board: Board;
10
10
  getNthVector: (index: number) => Cell[];
11
- numberOfVectors: number;
12
11
  PatternModel: new (parameters: {
13
12
  board: Board;
14
13
  cells: Cell[];
15
14
  }) => P;
15
+ vectorsCount: number;
16
16
  }): P[];
17
- generateVectors({ getNthVector, numberOfVectors, }: {
17
+ generateVectors({ getNthVector, vectorsCount, }: {
18
18
  getNthVector: (index: number) => Cell[];
19
- numberOfVectors: number;
19
+ vectorsCount: number;
20
20
  }): Cell[][];
21
21
  generateCellsPatterns<P extends Pattern>({ board, cells, PatternModel, }: {
22
22
  board: Board;
@@ -12,25 +12,25 @@ class PatternsGenerator {
12
12
  return this.generatePatterns({
13
13
  board,
14
14
  getNthVector: (index) => board.getRow(index),
15
- numberOfVectors: this.config.boardHeight,
16
15
  PatternModel: types_1.HorizontalPattern,
16
+ vectorsCount: this.config.boardHeight,
17
17
  });
18
18
  }
19
19
  generateVertical(board) {
20
20
  return this.generatePatterns({
21
21
  board,
22
22
  getNthVector: (index) => board.getColumn(index),
23
- numberOfVectors: this.config.boardWidth,
24
23
  PatternModel: types_1.VerticalPattern,
24
+ vectorsCount: this.config.boardWidth,
25
25
  });
26
26
  }
27
- generatePatterns({ board, getNthVector, numberOfVectors, PatternModel, }) {
28
- return this.generateVectors({ getNthVector, numberOfVectors }).reduce((patterns, cells) => {
27
+ generatePatterns({ board, getNthVector, vectorsCount, PatternModel, }) {
28
+ return this.generateVectors({ getNthVector, vectorsCount }).reduce((patterns, cells) => {
29
29
  return patterns.concat(this.generateCellsPatterns({ board, PatternModel, cells }));
30
30
  }, []);
31
31
  }
32
- generateVectors({ getNthVector, numberOfVectors, }) {
33
- return Array(numberOfVectors)
32
+ generateVectors({ getNthVector, vectorsCount, }) {
33
+ return Array(vectorsCount)
34
34
  .fill(0)
35
35
  .map((_, index) => getNthVector(index));
36
36
  }
@@ -18,7 +18,7 @@ class ScoresCalculator {
18
18
  return this.calculatePatternScoreWithCollisions(pattern) + this.calculateBonusScore(pattern);
19
19
  }
20
20
  calculateBonusScore(pattern) {
21
- const areAllTilesUsed = pattern.getNumberOfEmptyCells() === this.config.maximumNumberOfCharacters;
21
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === this.config.maximumCharactersCount;
22
22
  return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
23
23
  }
24
24
  calculatePatternScoreWithCollisions(pattern) {
package/build/Solver.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const types_1 = require("@scrabble-solver/types");
7
- const uniqBy_1 = __importDefault(require("lodash/uniqBy"));
7
+ const getUniquePatterns_1 = __importDefault(require("./getUniquePatterns"));
8
8
  const PatternsFiller_1 = __importDefault(require("./PatternsFiller"));
9
9
  const PatternsGenerator_1 = __importDefault(require("./PatternsGenerator"));
10
10
  const ScoresCalculator_1 = __importDefault(require("./ScoresCalculator"));
@@ -17,11 +17,11 @@ class Solver {
17
17
  solve(board, tiles) {
18
18
  const patterns = this.patternsGenerator.generate(board);
19
19
  const filledPatterns = patterns.flatMap((pattern) => this.patternsFiller.fill(pattern, tiles));
20
- const uniquePatterns = (0, uniqBy_1.default)(filledPatterns, (pattern) => JSON.stringify(pattern.toJson()));
20
+ const uniquePatterns = (0, getUniquePatterns_1.default)(filledPatterns);
21
21
  const results = uniquePatterns.map((pattern, index) => new types_1.Result({
22
22
  cells: pattern.cells,
23
+ collisions: pattern.getCollisions().map((collision) => collision.cells),
23
24
  id: index,
24
- numberOfCollisions: pattern.getCollisions().length,
25
25
  points: this.scoresCalculator.calculate(pattern),
26
26
  }));
27
27
  return results;
@@ -0,0 +1,3 @@
1
+ import { Pattern } from '@scrabble-solver/types';
2
+ declare const getUniquePatterns: (patterns: Pattern[]) => Pattern[];
3
+ export default getUniquePatterns;
@@ -0,0 +1,25 @@
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
+ const getUniquePatterns = (patterns) => {
14
+ const hashes = new Set();
15
+ const uniquePatterns = [];
16
+ for (const pattern of patterns) {
17
+ const hash = getPatternHash(pattern);
18
+ if (!hashes.has(hash)) {
19
+ hashes.add(hash);
20
+ uniquePatterns.push(pattern);
21
+ }
22
+ }
23
+ return uniquePatterns;
24
+ };
25
+ exports.default = getUniquePatterns;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.8.5",
3
+ "version": "2.8.7",
4
4
  "description": "Scrabble Solver 2 - Solver",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -25,14 +25,12 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@kamilmielnik/trie": "^2.0.0",
28
- "@scrabble-solver/types": "^2.8.5",
29
- "lodash": "^4.17.21"
28
+ "@scrabble-solver/types": "^2.8.7"
30
29
  },
31
30
  "devDependencies": {
32
- "@scrabble-solver/configs": "^2.8.5",
33
- "@scrabble-solver/constants": "^2.8.5",
34
- "@scrabble-solver/dictionaries": "^2.8.5",
35
- "@types/lodash": "^4.14.186"
31
+ "@scrabble-solver/configs": "^2.8.7",
32
+ "@scrabble-solver/constants": "^2.8.7",
33
+ "@scrabble-solver/dictionaries": "^2.8.7"
36
34
  },
37
- "gitHead": "79ba3664458e7dc8d805599a3cf3cd1faba86309"
35
+ "gitHead": "879bf9b68f27fa3d530d0582fd8fbbcd5c8b150b"
38
36
  }
@@ -15,7 +15,7 @@ class PatternsFiller {
15
15
  public fill(pattern: Pattern, tiles: Tile[]): Pattern[] {
16
16
  const patterns: Pattern[] = [];
17
17
 
18
- if (pattern.getNumberOfEmptyCells() > tiles.length) {
18
+ if (pattern.getEmptyCellsCount() > tiles.length) {
19
19
  return [];
20
20
  }
21
21
 
@@ -8,7 +8,7 @@ const board = Board.fromStringArray([' t ', 'do ', ' ']);
8
8
  const patternsGenerator = new PatternsGenerator({
9
9
  boardHeight: 3,
10
10
  boardWidth: 3,
11
- maximumNumberOfCharacters: 7,
11
+ maximumCharactersCount: 7,
12
12
  } as Config);
13
13
 
14
14
  describe('PatternsGenerator', () => {
@@ -45,7 +45,7 @@ describe('PatternsGenerator', () => {
45
45
  it('generates vectors', () => {
46
46
  const vectors = patternsGenerator.generateVectors({
47
47
  getNthVector: () => [],
48
- numberOfVectors: 3,
48
+ vectorsCount: 3,
49
49
  });
50
50
  expect(vectors.length).toBe(3);
51
51
  expect(vectors).toEqual([[], [], []]);
@@ -15,8 +15,8 @@ class PatternsGenerator {
15
15
  return this.generatePatterns({
16
16
  board,
17
17
  getNthVector: (index) => board.getRow(index),
18
- numberOfVectors: this.config.boardHeight,
19
18
  PatternModel: HorizontalPattern,
19
+ vectorsCount: this.config.boardHeight,
20
20
  });
21
21
  }
22
22
 
@@ -24,35 +24,35 @@ class PatternsGenerator {
24
24
  return this.generatePatterns({
25
25
  board,
26
26
  getNthVector: (index) => board.getColumn(index),
27
- numberOfVectors: this.config.boardWidth,
28
27
  PatternModel: VerticalPattern,
28
+ vectorsCount: this.config.boardWidth,
29
29
  });
30
30
  }
31
31
 
32
32
  public generatePatterns<P extends Pattern>({
33
33
  board,
34
34
  getNthVector,
35
- numberOfVectors,
35
+ vectorsCount,
36
36
  PatternModel,
37
37
  }: {
38
38
  board: Board;
39
39
  getNthVector: (index: number) => Cell[];
40
- numberOfVectors: number;
41
40
  PatternModel: new (parameters: { board: Board; cells: Cell[] }) => P;
41
+ vectorsCount: number;
42
42
  }): P[] {
43
- return this.generateVectors({ getNthVector, numberOfVectors }).reduce<P[]>((patterns, cells) => {
43
+ return this.generateVectors({ getNthVector, vectorsCount }).reduce<P[]>((patterns, cells) => {
44
44
  return patterns.concat(this.generateCellsPatterns<P>({ board, PatternModel, cells }));
45
45
  }, []);
46
46
  }
47
47
 
48
48
  public generateVectors({
49
49
  getNthVector,
50
- numberOfVectors,
50
+ vectorsCount,
51
51
  }: {
52
52
  getNthVector: (index: number) => Cell[];
53
- numberOfVectors: number;
53
+ vectorsCount: number;
54
54
  }): Cell[][] {
55
- return Array(numberOfVectors)
55
+ return Array(vectorsCount)
56
56
  .fill(0)
57
57
  .map((_, index) => getNthVector(index));
58
58
  }
@@ -13,7 +13,7 @@ class ScoresCalculator {
13
13
  }
14
14
 
15
15
  public calculateBonusScore(pattern: Pattern): number {
16
- const areAllTilesUsed = pattern.getNumberOfEmptyCells() === this.config.maximumNumberOfCharacters;
16
+ const areAllTilesUsed = pattern.getEmptyCellsCount() === this.config.maximumCharactersCount;
17
17
  return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
18
18
  }
19
19
 
package/src/Solver.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Trie } from '@kamilmielnik/trie';
2
2
  import { Board, Config, Result, Tile } from '@scrabble-solver/types';
3
- import uniqBy from 'lodash/uniqBy';
4
3
 
4
+ import getUniquePatterns from './getUniquePatterns';
5
5
  import PatternsFiller from './PatternsFiller';
6
6
  import PatternsGenerator from './PatternsGenerator';
7
7
  import ScoresCalculator from './ScoresCalculator';
@@ -22,13 +22,13 @@ class Solver {
22
22
  public solve(board: Board, tiles: Tile[]): Result[] {
23
23
  const patterns = this.patternsGenerator.generate(board);
24
24
  const filledPatterns = patterns.flatMap((pattern) => this.patternsFiller.fill(pattern, tiles));
25
- const uniquePatterns = uniqBy(filledPatterns, (pattern) => JSON.stringify(pattern.toJson()));
25
+ const uniquePatterns = getUniquePatterns(filledPatterns);
26
26
  const results = uniquePatterns.map(
27
27
  (pattern, index) =>
28
28
  new Result({
29
29
  cells: pattern.cells,
30
+ collisions: pattern.getCollisions().map((collision) => collision.cells),
30
31
  id: index,
31
- numberOfCollisions: pattern.getCollisions().length,
32
32
  points: this.scoresCalculator.calculate(pattern),
33
33
  }),
34
34
  );
@@ -0,0 +1,30 @@
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
+ const getUniquePatterns = (patterns: Pattern[]): Pattern[] => {
15
+ const hashes = new Set<string>();
16
+ const uniquePatterns: Pattern[] = [];
17
+
18
+ for (const pattern of patterns) {
19
+ const hash = getPatternHash(pattern);
20
+
21
+ if (!hashes.has(hash)) {
22
+ hashes.add(hash);
23
+ uniquePatterns.push(pattern);
24
+ }
25
+ }
26
+
27
+ return uniquePatterns;
28
+ };
29
+
30
+ export default getUniquePatterns;