@scrabble-solver/solver 2.15.10 → 2.15.11

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,13 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPatternScore = void 0;
4
+ const types_1 = require("@scrabble-solver/types");
4
5
  const getCellsScore_1 = require("./getCellsScore");
5
6
  const getPatternScore = (config, pattern) => {
6
7
  const areAllTilesUsed = pattern.getEmptyCellsCount() === config.rackSize;
7
- const bonusScore = areAllTilesUsed ? config.bingoScore : 0;
8
- const score = pattern
8
+ const baseScore = (0, getCellsScore_1.getCellsScore)(config, pattern.cells);
9
+ const collisionsScore = pattern
9
10
  .getCollisions()
10
- .reduce((sum, collision) => sum + (0, getCellsScore_1.getCellsScore)(config, collision.cells), (0, getCellsScore_1.getCellsScore)(config, pattern.cells));
11
- return score + bonusScore;
11
+ .reduce((sum, collision) => sum + (0, getCellsScore_1.getCellsScore)(config, collision.cells), 0);
12
+ if (areAllTilesUsed) {
13
+ if ((0, types_1.isScoreBingo)(config.bingo)) {
14
+ return baseScore + collisionsScore + config.bingo.score;
15
+ }
16
+ if ((0, types_1.isMultiplierBingo)(config.bingo)) {
17
+ return baseScore * config.bingo.multiplier + collisionsScore;
18
+ }
19
+ }
20
+ return baseScore + collisionsScore;
12
21
  };
13
22
  exports.getPatternScore = getPatternScore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scrabble-solver/solver",
3
- "version": "2.15.10",
3
+ "version": "2.15.11",
4
4
  "description": "Scrabble Solver 2 - Solver",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -24,12 +24,12 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@kamilmielnik/trie": "^4.0.0",
27
- "@scrabble-solver/types": "^2.15.10"
27
+ "@scrabble-solver/types": "^2.15.11"
28
28
  },
29
29
  "devDependencies": {
30
- "@scrabble-solver/configs": "^2.15.10",
31
- "@scrabble-solver/constants": "^2.15.10",
32
- "@scrabble-solver/dictionaries": "^2.15.10"
30
+ "@scrabble-solver/configs": "^2.15.11",
31
+ "@scrabble-solver/constants": "^2.15.11",
32
+ "@scrabble-solver/dictionaries": "^2.15.11"
33
33
  },
34
- "gitHead": "dab5a817c1bde1a3ebf8e8907215adf12af5cb27"
34
+ "gitHead": "4fa527098d5e67120adb7964777c044a09378332"
35
35
  }
@@ -3,68 +3,154 @@ import { Board, Cell, Game, HorizontalPattern, Locale, Pattern, Tile, VerticalPa
3
3
 
4
4
  import { getPatternScore } from './getPatternScore';
5
5
 
6
- const locale = Locale.PL_PL;
7
- const config = getConfig(Game.Literaki, locale);
8
- const board = Board.fromStringArray([
9
- ' kasom ',
10
- ' i ',
11
- ' napiją ',
12
- ' w i ',
13
- ' krabim ',
14
- ' z ',
15
- ' ę eh ',
16
- 'f s srać ',
17
- 'i z t s ',
18
- 'knebel e ',
19
- 'a ew warcz',
20
- 'ł żyło wody ',
21
- 'o pecyj chu',
22
- ' y ',
23
- ' t ',
24
- ]);
25
-
26
6
  describe('getPatternScore', () => {
27
- it('gives proper score without collisions', () => {
28
- const pattern = new Pattern(board, [
29
- new Cell({ x: 0, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: true }),
30
- new Cell({ x: 1, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
31
- new Cell({ x: 2, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
32
- new Cell({ x: 3, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
33
- new Cell({ x: 4, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
34
- new Cell({ x: 5, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
35
- new Cell({ x: 6, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
36
- new Cell({ x: 7, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: false }),
7
+ describe('Literaki - PL_PL', () => {
8
+ const config = getConfig(Game.Literaki, Locale.PL_PL);
9
+ const board = Board.fromStringArray([
10
+ ' kasom ',
11
+ ' i ',
12
+ ' napiją ',
13
+ ' w i ',
14
+ ' krabim ',
15
+ ' z ',
16
+ ' ę eh ',
17
+ 'f s srać ',
18
+ 'i z t s ',
19
+ 'knebel e ',
20
+ 'a ew warcz',
21
+ 'ł żyło wody ',
22
+ 'o pecyj chu',
23
+ ' y ',
24
+ ' t ',
37
25
  ]);
38
26
 
39
- expect(getPatternScore(config, pattern)).toBe(128);
40
- });
27
+ it('gives proper score without collisions (źaaaaaaź)', () => {
28
+ const pattern = new Pattern(board, [
29
+ new Cell({ x: 0, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: true }),
30
+ new Cell({ x: 1, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
31
+ new Cell({ x: 2, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
32
+ new Cell({ x: 3, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
33
+ new Cell({ x: 4, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
34
+ new Cell({ x: 5, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
35
+ new Cell({ x: 6, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
36
+ new Cell({ x: 7, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: false }),
37
+ ]);
41
38
 
42
- it('gives proper score with collisions', () => {
43
- const pattern = new VerticalPattern(board, [
44
- new Cell({ x: 2, y: 11, tile: new Tile({ character: 'l' }), isEmpty: true }),
45
- new Cell({ x: 2, y: 12, tile: new Tile({ character: 'i' }), isEmpty: true }),
46
- new Cell({ x: 2, y: 13, tile: new Tile({ character: 'n' }), isEmpty: true }),
47
- new Cell({ x: 2, y: 14, tile: new Tile({ character: 'o' }), isEmpty: true }),
48
- ]);
39
+ expect(getPatternScore(config, pattern)).toBe(128);
40
+ });
49
41
 
50
- expect(getPatternScore(config, pattern)).toBe(44);
51
- });
42
+ it('gives proper score with collisions (źaaaaaaź)', () => {
43
+ const pattern = new HorizontalPattern(board, [
44
+ new Cell({ x: 0, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: true }),
45
+ new Cell({ x: 1, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
46
+ new Cell({ x: 2, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
47
+ new Cell({ x: 3, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
48
+ new Cell({ x: 4, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
49
+ new Cell({ x: 5, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
50
+ new Cell({ x: 6, y: 0, tile: new Tile({ character: 'a' }), isEmpty: true }),
51
+ new Cell({ x: 7, y: 0, tile: new Tile({ character: 'ź' }), isEmpty: false }),
52
+ ]);
52
53
 
53
- it('gives proper score for blank', () => {
54
- const pattern = new HorizontalPattern(board, [
55
- new Cell({ x: 13, y: 14, tile: new Tile({ character: 'o', isBlank: true }), isEmpty: true }),
56
- new Cell({ x: 12, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
57
- ]);
54
+ expect(getPatternScore(config, pattern)).toBe(133);
55
+ });
56
+
57
+ it('gives proper score with collisions (lino)', () => {
58
+ const pattern = new VerticalPattern(board, [
59
+ new Cell({ x: 2, y: 11, tile: new Tile({ character: 'l' }), isEmpty: true }),
60
+ new Cell({ x: 2, y: 12, tile: new Tile({ character: 'i' }), isEmpty: true }),
61
+ new Cell({ x: 2, y: 13, tile: new Tile({ character: 'n' }), isEmpty: true }),
62
+ new Cell({ x: 2, y: 14, tile: new Tile({ character: 'o' }), isEmpty: true }),
63
+ ]);
64
+
65
+ expect(getPatternScore(config, pattern)).toBe(44);
66
+ });
67
+
68
+ it('gives proper score for blank', () => {
69
+ const pattern = new HorizontalPattern(board, [
70
+ new Cell({ x: 13, y: 14, tile: new Tile({ character: 'o', isBlank: true }), isEmpty: true }),
71
+ new Cell({ x: 12, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
72
+ ]);
73
+
74
+ expect(getPatternScore(config, pattern)).toBe(2);
75
+ });
58
76
 
59
- expect(getPatternScore(config, pattern)).toBe(2);
77
+ it('gives 0 score for unknown characters', () => {
78
+ const pattern = new HorizontalPattern(board, [
79
+ new Cell({ x: 13, y: 14, tile: new Tile({ character: '?', isBlank: false }), isEmpty: true }),
80
+ new Cell({ x: 12, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
81
+ ]);
82
+
83
+ expect(getPatternScore(config, pattern)).toBe(2);
84
+ });
85
+
86
+ it('gives 50 points bonus for bingo', () => {
87
+ const pattern = new HorizontalPattern(board, [
88
+ new Cell({ x: 6, y: 14, tile: new Tile({ character: 'p' }), isEmpty: true }),
89
+ new Cell({ x: 7, y: 14, tile: new Tile({ character: 'o' }), isEmpty: true }),
90
+ new Cell({ x: 8, y: 14, tile: new Tile({ character: 'r' }), isEmpty: true }),
91
+ new Cell({ x: 9, y: 14, tile: new Tile({ character: 'o' }), isEmpty: true }),
92
+ new Cell({ x: 10, y: 14, tile: new Tile({ character: 'w' }), isEmpty: true }),
93
+ new Cell({ x: 11, y: 14, tile: new Tile({ character: 'a', isBlank: true }), isEmpty: true }),
94
+ new Cell({ x: 11, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
95
+ new Cell({ x: 13, y: 14, tile: new Tile({ character: 'e' }), isEmpty: true }),
96
+ ]);
97
+
98
+ expect(getPatternScore(config, pattern)).toBe(59);
99
+ });
60
100
  });
61
101
 
62
- it('gives 0 score for unknown characters', () => {
63
- const pattern = new HorizontalPattern(board, [
64
- new Cell({ x: 13, y: 14, tile: new Tile({ character: '?', isBlank: false }), isEmpty: true }),
65
- new Cell({ x: 12, y: 14, tile: new Tile({ character: 't' }), isEmpty: false }),
66
- ]);
102
+ describe('Letter League - EN_US', () => {
103
+ const config = getConfig(Game.LetterLeague, Locale.EN_US);
104
+
105
+ it('gives double multiplier bonus for bingo without collisions', () => {
106
+ const board = Board.create(config.boardWidth, config.boardHeight);
107
+ const pattern = new HorizontalPattern(board, [
108
+ new Cell({ x: 13, y: 6, tile: new Tile({ character: 'r' }), isEmpty: true }),
109
+ new Cell({ x: 13, y: 7, tile: new Tile({ character: 'o' }), isEmpty: true }),
110
+ new Cell({ x: 13, y: 8, tile: new Tile({ character: 'm' }), isEmpty: true }),
111
+ new Cell({ x: 13, y: 9, tile: new Tile({ character: 'a' }), isEmpty: true }),
112
+ new Cell({ x: 13, y: 10, tile: new Tile({ character: 'i' }), isEmpty: true }),
113
+ new Cell({ x: 13, y: 11, tile: new Tile({ character: 'n' }), isEmpty: true }),
114
+ new Cell({ x: 13, y: 12, tile: new Tile({ character: 'e' }), isEmpty: true }),
115
+ ]);
116
+
117
+ expect(getPatternScore(config, pattern)).toBe(18);
118
+ });
119
+
120
+ it('gives double multiplier bonus for bingo with collisions', () => {
121
+ const board = Board.fromStringArray([
122
+ ' ',
123
+ ' ',
124
+ ' ',
125
+ ' ',
126
+ ' ',
127
+ ' ',
128
+ ' ',
129
+ ' ',
130
+ ' ',
131
+ ' ',
132
+ ' ',
133
+ ' ',
134
+ ' on ',
135
+ ' ',
136
+ ' ',
137
+ ' ',
138
+ ' ',
139
+ ' ',
140
+ ' ',
141
+ ]);
142
+
143
+ const pattern = new VerticalPattern(board, [
144
+ new Cell({ x: 13, y: 6, tile: new Tile({ character: 'r' }), isEmpty: true }),
145
+ new Cell({ x: 13, y: 7, tile: new Tile({ character: 'o' }), isEmpty: true }),
146
+ new Cell({ x: 13, y: 8, tile: new Tile({ character: 'm' }), isEmpty: true }),
147
+ new Cell({ x: 13, y: 9, tile: new Tile({ character: 'a' }), isEmpty: true }),
148
+ new Cell({ x: 13, y: 10, tile: new Tile({ character: 'i' }), isEmpty: true }),
149
+ new Cell({ x: 13, y: 11, tile: new Tile({ character: 'n' }), isEmpty: true }),
150
+ new Cell({ x: 13, y: 12, tile: new Tile({ character: 'e' }), isEmpty: true }),
151
+ ]);
67
152
 
68
- expect(getPatternScore(config, pattern)).toBe(2);
153
+ expect(getPatternScore(config, pattern)).toBe(21);
154
+ });
69
155
  });
70
156
  });
@@ -1,13 +1,23 @@
1
- import { Config, Pattern } from '@scrabble-solver/types';
1
+ import { Config, isMultiplierBingo, isScoreBingo, Pattern } from '@scrabble-solver/types';
2
2
 
3
3
  import { getCellsScore } from './getCellsScore';
4
4
 
5
5
  export const getPatternScore = (config: Config, pattern: Pattern) => {
6
6
  const areAllTilesUsed = pattern.getEmptyCellsCount() === config.rackSize;
7
- const bonusScore = areAllTilesUsed ? config.bingoScore : 0;
8
- const score = pattern
7
+ const baseScore = getCellsScore(config, pattern.cells);
8
+ const collisionsScore = pattern
9
9
  .getCollisions()
10
- .reduce((sum, collision) => sum + getCellsScore(config, collision.cells), getCellsScore(config, pattern.cells));
10
+ .reduce((sum, collision) => sum + getCellsScore(config, collision.cells), 0);
11
11
 
12
- return score + bonusScore;
12
+ if (areAllTilesUsed) {
13
+ if (isScoreBingo(config.bingo)) {
14
+ return baseScore + collisionsScore + config.bingo.score;
15
+ }
16
+
17
+ if (isMultiplierBingo(config.bingo)) {
18
+ return baseScore * config.bingo.multiplier + collisionsScore;
19
+ }
20
+ }
21
+
22
+ return baseScore + collisionsScore;
13
23
  };