@scrabble-solver/solver 2.8.1 → 2.8.3

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.
@@ -1,104 +1,74 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
- if (ar || !(i in from)) {
21
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
- ar[i] = from[i];
23
- }
24
- }
25
- return to.concat(ar || Array.prototype.slice.call(from));
26
- };
27
2
  Object.defineProperty(exports, "__esModule", { value: true });
28
- var constants_1 = require("@scrabble-solver/constants");
29
- var types_1 = require("@scrabble-solver/types");
30
- var PatternsFiller = /** @class */ (function () {
31
- function PatternsFiller(config, trie) {
3
+ const constants_1 = require("@scrabble-solver/constants");
4
+ const types_1 = require("@scrabble-solver/types");
5
+ class PatternsFiller {
6
+ constructor(config, trie) {
32
7
  this.config = config;
33
8
  this.trie = trie;
34
9
  }
35
- PatternsFiller.prototype.fill = function (pattern, tiles) {
36
- var patterns = [];
10
+ fill(pattern, tiles) {
11
+ const patterns = [];
37
12
  if (pattern.getNumberOfEmptyCells() > tiles.length) {
38
13
  return [];
39
14
  }
40
- var onPatternFound = function (newPattern) { return patterns.push(newPattern); };
41
- var tilesPermutations = this.generateBlankTilesPermutations(tiles);
42
- for (var index = 0; index < tilesPermutations.length; ++index) {
43
- var tilesPermutation = tilesPermutations[index];
15
+ const onPatternFound = (newPattern) => patterns.push(newPattern);
16
+ const tilesPermutations = this.generateBlankTilesPermutations(tiles);
17
+ for (let index = 0; index < tilesPermutations.length; ++index) {
18
+ const tilesPermutation = tilesPermutations[index];
44
19
  this.fillPattern(pattern, String(pattern), tilesPermutation, onPatternFound);
45
20
  }
46
21
  return patterns;
47
- };
48
- PatternsFiller.prototype.fillPattern = function (pattern, word, tiles, onPatternFound) {
49
- var indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
22
+ }
23
+ fillPattern(pattern, word, tiles, onPatternFound) {
24
+ const indexOfFirstCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
50
25
  if (indexOfFirstCellWithoutTile === -1) {
51
26
  if (this.canAddPattern(pattern, word)) {
52
27
  onPatternFound(pattern.clone());
53
28
  }
54
29
  }
55
30
  else {
56
- for (var index = 0; index < tiles.length; ++index) {
57
- var tile = tiles[index];
58
- var remainingTiles = tiles.slice(0, index).concat(tiles.slice(index + 1));
59
- var previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
31
+ for (let index = 0; index < tiles.length; ++index) {
32
+ const tile = tiles[index];
33
+ const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
60
34
  pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
61
- var indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
62
- var indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
63
- var newWordPrefix = word.substring(0, indexOfFirstEmptyLetter) + tile.character;
64
- var newWord = newWordPrefix + word.substring(indexOfFirstEmptyLetter + 1);
35
+ const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
36
+ const indexOfFirstEmptyLetter = word.indexOf(constants_1.EMPTY_CELL);
37
+ const newWordPrefix = word.substring(0, indexOfFirstEmptyLetter) + tile.character;
38
+ const newWord = newWordPrefix + word.substring(indexOfFirstEmptyLetter + 1);
65
39
  if (indexOfNextCellWithoutTile === -1) {
66
40
  if (this.canAddPattern(pattern, newWord)) {
67
41
  onPatternFound(pattern.clone());
68
42
  }
69
43
  }
70
44
  else if (this.trie.hasPrefix(newWordPrefix)) {
71
- this.fillPattern(pattern, newWord, remainingTiles, onPatternFound);
45
+ tiles.splice(index, 1);
46
+ this.fillPattern(pattern, newWord, tiles, onPatternFound);
47
+ tiles.splice(index, 0, tile);
72
48
  }
73
49
  pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
74
50
  }
75
51
  }
76
- };
77
- PatternsFiller.prototype.canAddPattern = function (pattern, word) {
78
- var _this = this;
52
+ }
53
+ canAddPattern(pattern, word) {
79
54
  return (this.trie.has(word) &&
80
55
  pattern
81
56
  .getCollisions()
82
57
  .map(String)
83
- .every(function (collision) { return _this.trie.has(collision); }));
84
- };
85
- PatternsFiller.prototype.generateBlankTilesPermutations = function (tiles) {
86
- var _this = this;
87
- var alphabet = this.config.alphabet;
88
- var firstBlankIndex = tiles.findIndex(function (_a) {
89
- var character = _a.character, isBlank = _a.isBlank;
90
- return isBlank && !alphabet.includes(character);
91
- });
58
+ .every((collision) => this.trie.has(collision)));
59
+ }
60
+ generateBlankTilesPermutations(tiles) {
61
+ const { alphabet } = this.config;
62
+ const firstBlankIndex = tiles.findIndex(({ character, isBlank }) => isBlank && !alphabet.includes(character));
92
63
  if (firstBlankIndex === -1) {
93
64
  return [tiles];
94
65
  }
95
- var remainingTiles = tiles.slice(0, firstBlankIndex).concat(tiles.slice(firstBlankIndex + 1));
96
- return this.config.alphabet.reduce(function (permutations, character) {
97
- var newTile = new types_1.Tile({ character: character, isBlank: true });
98
- var newTiles = __spreadArray(__spreadArray([], __read(remainingTiles), false), [newTile], false);
99
- return permutations.concat(_this.generateBlankTilesPermutations(newTiles));
66
+ const remainingTiles = tiles.slice(0, firstBlankIndex).concat(tiles.slice(firstBlankIndex + 1));
67
+ return this.config.alphabet.reduce((permutations, character) => {
68
+ const newTile = new types_1.Tile({ character, isBlank: true });
69
+ const newTiles = [...remainingTiles, newTile];
70
+ return permutations.concat(this.generateBlankTilesPermutations(newTiles));
100
71
  }, []);
101
- };
102
- return PatternsFiller;
103
- }());
72
+ }
73
+ }
104
74
  exports.default = PatternsFiller;
@@ -1,95 +1,62 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
- if (ar || !(i in from)) {
21
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
- ar[i] = from[i];
23
- }
24
- }
25
- return to.concat(ar || Array.prototype.slice.call(from));
26
- };
27
2
  Object.defineProperty(exports, "__esModule", { value: true });
28
- var types_1 = require("@scrabble-solver/types");
29
- var PatternsGenerator = /** @class */ (function () {
30
- function PatternsGenerator(config) {
3
+ const types_1 = require("@scrabble-solver/types");
4
+ class PatternsGenerator {
5
+ constructor(config) {
31
6
  this.config = config;
32
7
  }
33
- PatternsGenerator.prototype.generate = function (board) {
34
- return __spreadArray(__spreadArray([], __read(this.generateHorizontal(board)), false), __read(this.generateVertical(board)), false);
35
- };
36
- PatternsGenerator.prototype.generateHorizontal = function (board) {
8
+ generate(board) {
9
+ return [...this.generateHorizontal(board), ...this.generateVertical(board)];
10
+ }
11
+ generateHorizontal(board) {
37
12
  return this.generatePatterns({
38
- board: board,
39
- getNthVector: function (index) { return board.getRow(index); },
13
+ board,
14
+ getNthVector: (index) => board.getRow(index),
40
15
  numberOfVectors: this.config.boardHeight,
41
16
  PatternModel: types_1.HorizontalPattern,
42
17
  });
43
- };
44
- PatternsGenerator.prototype.generateVertical = function (board) {
18
+ }
19
+ generateVertical(board) {
45
20
  return this.generatePatterns({
46
- board: board,
47
- getNthVector: function (index) { return board.getColumn(index); },
21
+ board,
22
+ getNthVector: (index) => board.getColumn(index),
48
23
  numberOfVectors: this.config.boardWidth,
49
24
  PatternModel: types_1.VerticalPattern,
50
25
  });
51
- };
52
- PatternsGenerator.prototype.generatePatterns = function (_a) {
53
- var _this = this;
54
- var board = _a.board, getNthVector = _a.getNthVector, numberOfVectors = _a.numberOfVectors, PatternModel = _a.PatternModel;
55
- return this.generateVectors({ getNthVector: getNthVector, numberOfVectors: numberOfVectors }).reduce(function (patterns, cells) {
56
- return patterns.concat(_this.generateCellsPatterns({ board: board, PatternModel: PatternModel, cells: cells }));
26
+ }
27
+ generatePatterns({ board, getNthVector, numberOfVectors, PatternModel, }) {
28
+ return this.generateVectors({ getNthVector, numberOfVectors }).reduce((patterns, cells) => {
29
+ return patterns.concat(this.generateCellsPatterns({ board, PatternModel, cells }));
57
30
  }, []);
58
- };
59
- PatternsGenerator.prototype.generateVectors = function (_a) {
60
- var getNthVector = _a.getNthVector, numberOfVectors = _a.numberOfVectors;
31
+ }
32
+ generateVectors({ getNthVector, numberOfVectors, }) {
61
33
  return Array(numberOfVectors)
62
34
  .fill(0)
63
- .map(function (_, index) { return getNthVector(index); });
64
- };
65
- PatternsGenerator.prototype.generateCellsPatterns = function (_a) {
66
- var _this = this;
67
- var board = _a.board, cells = _a.cells, PatternModel = _a.PatternModel;
68
- return this.generateStartIndices(cells).reduce(function (patterns, startIndex) {
69
- return patterns.concat(_this.generateEndIndices(cells, startIndex).reduce(function (placeablePatterns, endIndex) {
70
- var pattern = new PatternModel({
71
- board: board,
72
- cells: cells.slice(startIndex, endIndex + 1),
73
- });
74
- if (pattern.canBePlaced(_this.config)) {
75
- placeablePatterns.push(pattern);
76
- }
77
- return placeablePatterns;
78
- }, []));
79
- }, []);
80
- };
81
- PatternsGenerator.prototype.generateStartIndices = function (cells) {
35
+ .map((_, index) => getNthVector(index));
36
+ }
37
+ generateCellsPatterns({ board, cells, PatternModel, }) {
38
+ return this.generateStartIndices(cells).reduce((patterns, startIndex) => patterns.concat(this.generateEndIndices(cells, startIndex).reduce((placeablePatterns, endIndex) => {
39
+ const pattern = new PatternModel({
40
+ board,
41
+ cells: cells.slice(startIndex, endIndex + 1),
42
+ });
43
+ if (pattern.canBePlaced(this.config)) {
44
+ placeablePatterns.push(pattern);
45
+ }
46
+ return placeablePatterns;
47
+ }, [])), []);
48
+ }
49
+ generateStartIndices(cells) {
82
50
  return Array(cells.length - 1)
83
51
  .fill(0)
84
- .map(function (_, startIndex) { return startIndex; })
85
- .filter(function (startIndex) { return startIndex === 0 || !cells[startIndex - 1].hasTile(); });
86
- };
87
- PatternsGenerator.prototype.generateEndIndices = function (cells, startIndex) {
52
+ .map((_, startIndex) => startIndex)
53
+ .filter((startIndex) => startIndex === 0 || !cells[startIndex - 1].hasTile());
54
+ }
55
+ generateEndIndices(cells, startIndex) {
88
56
  return Array(cells.length - startIndex - 1)
89
57
  .fill(0)
90
- .map(function (_, endIndex) { return endIndex + startIndex + 1; })
91
- .filter(function (endIndex) { return endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile(); });
92
- };
93
- return PatternsGenerator;
94
- }());
58
+ .map((_, endIndex) => endIndex + startIndex + 1)
59
+ .filter((endIndex) => endIndex >= cells.length - 1 || !cells[endIndex + 1].hasTile());
60
+ }
61
+ }
95
62
  exports.default = PatternsGenerator;
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var constants_1 = require("@scrabble-solver/constants");
4
- var ScoresCalculator = /** @class */ (function () {
5
- function ScoresCalculator(config) {
6
- var _this = this;
7
- this.reduceCellScore = function (_a, cell) {
8
- var multiplier = _a.multiplier, score = _a.score;
9
- var bonus = _this.config.getCellBonus(cell);
10
- var _b = bonus && bonus.canApply(_this.config, cell) ? bonus.value : constants_1.NO_BONUS, characterMultiplier = _b.characterMultiplier, wordMultiplier = _b.wordMultiplier;
11
- var characterScore = cell.tile.isBlank ? _this.config.blankScore : _this.config.pointsMap[cell.tile.character];
3
+ const constants_1 = require("@scrabble-solver/constants");
4
+ class ScoresCalculator {
5
+ constructor(config) {
6
+ this.reduceCellScore = ({ multiplier, score }, cell) => {
7
+ const bonus = this.config.getCellBonus(cell);
8
+ const { characterMultiplier, wordMultiplier } = bonus && bonus.canApply(this.config, cell) ? bonus.value : constants_1.NO_BONUS;
9
+ const characterScore = cell.tile.isBlank ? this.config.blankScore : this.config.pointsMap[cell.tile.character];
12
10
  return {
13
11
  multiplier: multiplier * wordMultiplier,
14
12
  score: score + characterScore * characterMultiplier,
@@ -16,26 +14,24 @@ var ScoresCalculator = /** @class */ (function () {
16
14
  };
17
15
  this.config = config;
18
16
  }
19
- ScoresCalculator.prototype.calculate = function (pattern) {
17
+ calculate(pattern) {
20
18
  return this.calculatePatternScoreWithCollisions(pattern) + this.calculateBonusScore(pattern);
21
- };
22
- ScoresCalculator.prototype.calculateBonusScore = function (pattern) {
23
- var areAllTilesUsed = pattern.getNumberOfEmptyCells() === this.config.maximumNumberOfCharacters;
19
+ }
20
+ calculateBonusScore(pattern) {
21
+ const areAllTilesUsed = pattern.getNumberOfEmptyCells() === this.config.maximumNumberOfCharacters;
24
22
  return areAllTilesUsed ? this.config.allTilesBonusScore : 0;
25
- };
26
- ScoresCalculator.prototype.calculatePatternScoreWithCollisions = function (pattern) {
27
- var _this = this;
23
+ }
24
+ calculatePatternScoreWithCollisions(pattern) {
28
25
  return pattern
29
26
  .getCollisions()
30
- .reduce(function (patternsScore, collisionPattern) { return patternsScore + _this.calculatePatternScore(collisionPattern); }, this.calculatePatternScore(pattern));
31
- };
32
- ScoresCalculator.prototype.calculatePatternScore = function (pattern) {
33
- var _a = pattern.cells.reduce(this.reduceCellScore, {
27
+ .reduce((patternsScore, collisionPattern) => patternsScore + this.calculatePatternScore(collisionPattern), this.calculatePatternScore(pattern));
28
+ }
29
+ calculatePatternScore(pattern) {
30
+ const { multiplier, score } = pattern.cells.reduce(this.reduceCellScore, {
34
31
  multiplier: 1,
35
32
  score: 0,
36
- }), multiplier = _a.multiplier, score = _a.score;
33
+ });
37
34
  return score * multiplier;
38
- };
39
- return ScoresCalculator;
40
- }());
35
+ }
36
+ }
41
37
  exports.default = ScoresCalculator;
package/build/Solver.js CHANGED
@@ -3,33 +3,29 @@ 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
- var types_1 = require("@scrabble-solver/types");
7
- var uniqBy_1 = __importDefault(require("lodash/uniqBy"));
8
- var PatternsFiller_1 = __importDefault(require("./PatternsFiller"));
9
- var PatternsGenerator_1 = __importDefault(require("./PatternsGenerator"));
10
- var ScoresCalculator_1 = __importDefault(require("./ScoresCalculator"));
11
- var Solver = /** @class */ (function () {
12
- function Solver(config, trie) {
6
+ const types_1 = require("@scrabble-solver/types");
7
+ const uniqBy_1 = __importDefault(require("lodash/uniqBy"));
8
+ const PatternsFiller_1 = __importDefault(require("./PatternsFiller"));
9
+ const PatternsGenerator_1 = __importDefault(require("./PatternsGenerator"));
10
+ const ScoresCalculator_1 = __importDefault(require("./ScoresCalculator"));
11
+ class Solver {
12
+ constructor(config, trie) {
13
13
  this.patternsFiller = new PatternsFiller_1.default(config, trie);
14
14
  this.patternsGenerator = new PatternsGenerator_1.default(config);
15
15
  this.scoresCalculator = new ScoresCalculator_1.default(config);
16
16
  }
17
- Solver.prototype.solve = function (board, tiles) {
18
- var _this = this;
19
- var patterns = this.patternsGenerator
17
+ solve(board, tiles) {
18
+ const patterns = this.patternsGenerator
20
19
  .generate(board)
21
- .reduce(function (filledPatterns, pattern) { return filledPatterns.concat(_this.patternsFiller.fill(pattern, tiles)); }, []);
22
- var uniquePatterns = (0, uniqBy_1.default)(patterns, function (pattern) { return JSON.stringify(pattern.toJson()); });
23
- var results = uniquePatterns.map(function (pattern, index) {
24
- return new types_1.Result({
25
- cells: pattern.cells,
26
- id: index,
27
- numberOfCollisions: pattern.getCollisions().length,
28
- points: _this.scoresCalculator.calculate(pattern),
29
- });
30
- });
20
+ .reduce((filledPatterns, pattern) => filledPatterns.concat(this.patternsFiller.fill(pattern, tiles)), []);
21
+ const uniquePatterns = (0, uniqBy_1.default)(patterns, (pattern) => JSON.stringify(pattern.toJson()));
22
+ const results = uniquePatterns.map((pattern, index) => new types_1.Result({
23
+ cells: pattern.cells,
24
+ id: index,
25
+ numberOfCollisions: pattern.getCollisions().length,
26
+ points: this.scoresCalculator.calculate(pattern),
27
+ }));
31
28
  return results;
32
- };
33
- return Solver;
34
- }());
29
+ }
30
+ }
35
31
  exports.default = Solver;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "description": "Scrabble Solver 2 - Solver",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -25,14 +25,14 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@kamilmielnik/trie": "^1.0.3",
28
- "@scrabble-solver/types": "^2.8.1",
28
+ "@scrabble-solver/types": "^2.8.3",
29
29
  "lodash": "^4.17.21"
30
30
  },
31
31
  "devDependencies": {
32
- "@scrabble-solver/configs": "^2.8.1",
33
- "@scrabble-solver/constants": "^2.8.1",
34
- "@scrabble-solver/dictionaries": "^2.8.1",
32
+ "@scrabble-solver/configs": "^2.8.3",
33
+ "@scrabble-solver/constants": "^2.8.3",
34
+ "@scrabble-solver/dictionaries": "^2.8.3",
35
35
  "@types/lodash": "^4.14.185"
36
36
  },
37
- "gitHead": "994d5ef4a195cda08f7a907b8b1343bbc145801e"
37
+ "gitHead": "116f214733e7ad071044f556bcf67e867da3d9ca"
38
38
  }
@@ -45,7 +45,6 @@ class PatternsFiller {
45
45
  } else {
46
46
  for (let index = 0; index < tiles.length; ++index) {
47
47
  const tile = tiles[index];
48
- const remainingTiles = tiles.slice(0, index).concat(tiles.slice(index + 1));
49
48
  const previousTile = pattern.cells[indexOfFirstCellWithoutTile].tile;
50
49
  pattern.cells[indexOfFirstCellWithoutTile].tile = tile;
51
50
  const indexOfNextCellWithoutTile = pattern.getIndexOfFirstCellWithoutTile();
@@ -57,7 +56,9 @@ class PatternsFiller {
57
56
  onPatternFound(pattern.clone());
58
57
  }
59
58
  } else if (this.trie.hasPrefix(newWordPrefix)) {
60
- this.fillPattern(pattern, newWord, remainingTiles, onPatternFound);
59
+ tiles.splice(index, 1);
60
+ this.fillPattern(pattern, newWord, tiles, onPatternFound);
61
+ tiles.splice(index, 0, tile);
61
62
  }
62
63
  pattern.cells[indexOfFirstCellWithoutTile].tile = previousTile;
63
64
  }