@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.
- package/build/getPatternScore.js +13 -4
- package/package.json +6 -6
- package/src/getPatternScore.test.ts +139 -53
- package/src/getPatternScore.ts +15 -5
package/build/getPatternScore.js
CHANGED
|
@@ -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
|
|
8
|
-
const
|
|
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),
|
|
11
|
-
|
|
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.
|
|
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.
|
|
27
|
+
"@scrabble-solver/types": "^2.15.11"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@scrabble-solver/configs": "^2.15.
|
|
31
|
-
"@scrabble-solver/constants": "^2.15.
|
|
32
|
-
"@scrabble-solver/dictionaries": "^2.15.
|
|
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": "
|
|
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
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
153
|
+
expect(getPatternScore(config, pattern)).toBe(21);
|
|
154
|
+
});
|
|
69
155
|
});
|
|
70
156
|
});
|
package/src/getPatternScore.ts
CHANGED
|
@@ -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
|
|
8
|
-
const
|
|
7
|
+
const baseScore = getCellsScore(config, pattern.cells);
|
|
8
|
+
const collisionsScore = pattern
|
|
9
9
|
.getCollisions()
|
|
10
|
-
.reduce((sum, collision) => sum + getCellsScore(config, collision.cells),
|
|
10
|
+
.reduce((sum, collision) => sum + getCellsScore(config, collision.cells), 0);
|
|
11
11
|
|
|
12
|
-
|
|
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
|
};
|