chess-moments 1.2.2 → 1.4.0
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,7 +1,7 @@
|
|
|
1
1
|
const prettify = require('./prettify');
|
|
2
2
|
const shape = require('./shape');
|
|
3
3
|
|
|
4
|
-
module.exports = ({ depth, move, fen, comment, from, to }) => {
|
|
4
|
+
module.exports = ({ depth, move, fen, comment, suffix, from, to }) => {
|
|
5
5
|
const moment = { depth, fen };
|
|
6
6
|
if (move) {
|
|
7
7
|
moment.move = move;
|
|
@@ -20,6 +20,9 @@ module.exports = ({ depth, move, fen, comment, from, to }) => {
|
|
|
20
20
|
moment.shapes = shapes;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
if (suffix) {
|
|
24
|
+
moment.suffix = suffix;
|
|
25
|
+
}
|
|
23
26
|
|
|
24
27
|
return moment;
|
|
25
28
|
};
|
|
@@ -4,6 +4,7 @@ const getNextMoments = require('./get-next-moments');
|
|
|
4
4
|
const getPrevMoment = require('./get-prev-moment');
|
|
5
5
|
const momentsToPgn = require('./moments-to-pgn');
|
|
6
6
|
const moveTrainer = require('./move-trainer');
|
|
7
|
+
const promoteMainline = require('./promote-mainline');
|
|
7
8
|
|
|
8
9
|
module.exports = {
|
|
9
10
|
addMomentToTree,
|
|
@@ -12,4 +13,5 @@ module.exports = {
|
|
|
12
13
|
getPrevMoment,
|
|
13
14
|
momentsToPgn,
|
|
14
15
|
moveTrainer,
|
|
16
|
+
promoteMainline,
|
|
15
17
|
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const promoteMainline = (moments, current) => {
|
|
2
|
+
if (!current || current.depth === 1) return moments;
|
|
3
|
+
|
|
4
|
+
const currentDepth = current.depth;
|
|
5
|
+
const targetDepth = currentDepth - 1;
|
|
6
|
+
|
|
7
|
+
// Find sideline position marker
|
|
8
|
+
let sidelinePositionIndex = -1;
|
|
9
|
+
for (let i = 0; i < current.index; i++) {
|
|
10
|
+
if (moments[i].depth === currentDepth && !moments[i].move) {
|
|
11
|
+
sidelinePositionIndex = i;
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (sidelinePositionIndex === -1) return moments;
|
|
16
|
+
|
|
17
|
+
// Find end of sideline window (end of a window = next position at the same depth OR first lower depth)
|
|
18
|
+
let sidelineEndIndex = moments.length;
|
|
19
|
+
for (let i = sidelinePositionIndex + 1; i < moments.length; i++) {
|
|
20
|
+
if (
|
|
21
|
+
(moments[i].depth === currentDepth && !moments[i].move) ||
|
|
22
|
+
moments[i].depth < currentDepth
|
|
23
|
+
) {
|
|
24
|
+
sidelineEndIndex = i;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Find mainline move to replace
|
|
30
|
+
let targetMoveIndex = -1;
|
|
31
|
+
for (let i = sidelinePositionIndex - 1; i >= 0; i--) {
|
|
32
|
+
if (moments[i].depth === targetDepth && moments[i].move) {
|
|
33
|
+
targetMoveIndex = i;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (targetMoveIndex === -1) return moments;
|
|
38
|
+
|
|
39
|
+
// Find end of mainline segment to demote
|
|
40
|
+
let targetSegmentEndIndex = moments.length;
|
|
41
|
+
let seenTargetDepthMove = false;
|
|
42
|
+
for (let i = targetMoveIndex + 1; i < moments.length; i++) {
|
|
43
|
+
const moment = moments[i];
|
|
44
|
+
|
|
45
|
+
if (moment.depth === targetDepth && moment.move) {
|
|
46
|
+
seenTargetDepthMove = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (moment.depth < targetDepth) {
|
|
50
|
+
targetSegmentEndIndex = i;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (moment.depth === targetDepth && !moment.move && seenTargetDepthMove) {
|
|
55
|
+
targetSegmentEndIndex = i;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const demotedIndices = new Set([targetMoveIndex]);
|
|
61
|
+
const demotedMoves = [{ ...moments[targetMoveIndex], depth: currentDepth }];
|
|
62
|
+
|
|
63
|
+
for (let i = targetMoveIndex + 1; i < targetSegmentEndIndex; i++) {
|
|
64
|
+
if (moments[i].depth === targetDepth && moments[i].move) {
|
|
65
|
+
demotedIndices.add(i);
|
|
66
|
+
demotedMoves.push({ ...moments[i], depth: currentDepth });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Rebuild the moments array by promoting the current move to the mainline depth,
|
|
71
|
+
// demoting the old mainline sequence into the sideline, preserving order of
|
|
72
|
+
// unaffected moves, and adjusting depths/indices accordingly.
|
|
73
|
+
const result = [];
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < targetMoveIndex; i++) {
|
|
76
|
+
result.push({ ...moments[i] });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
result.push({ ...moments[current.index], depth: targetDepth });
|
|
80
|
+
|
|
81
|
+
for (let i = targetMoveIndex + 1; i < sidelinePositionIndex; i++) {
|
|
82
|
+
if (!demotedIndices.has(i)) {
|
|
83
|
+
result.push({ ...moments[i] });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
result.push({ ...moments[sidelinePositionIndex] });
|
|
88
|
+
for (const move of demotedMoves) {
|
|
89
|
+
result.push(move);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (let i = sidelinePositionIndex + 1; i < sidelineEndIndex; i++) {
|
|
93
|
+
if (i === current.index) continue;
|
|
94
|
+
|
|
95
|
+
const moment = moments[i];
|
|
96
|
+
if (moment.depth === currentDepth && moment.move) {
|
|
97
|
+
result.push({ ...moment, depth: targetDepth });
|
|
98
|
+
} else {
|
|
99
|
+
result.push({ ...moment });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
for (let i = sidelineEndIndex; i < moments.length; i++) {
|
|
104
|
+
if (!demotedIndices.has(i)) {
|
|
105
|
+
result.push({ ...moments[i] });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Reassign indices
|
|
110
|
+
result.forEach((m, i) => {
|
|
111
|
+
m.index = i;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return result;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
module.exports = promoteMainline;
|
package/functions/parser.js
CHANGED
|
@@ -12,8 +12,12 @@ module.exports = (moves, fen = initial, depth = 1) => {
|
|
|
12
12
|
chess.undo();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
const first = moment.build({
|
|
15
|
+
// First moment does not have a move
|
|
16
|
+
const first = moment.build({
|
|
17
|
+
depth,
|
|
18
|
+
comment: chess.getComment(),
|
|
19
|
+
fen: chess.fen(),
|
|
20
|
+
});
|
|
17
21
|
|
|
18
22
|
const moments = history.map((item) => {
|
|
19
23
|
chess.move(item.san);
|
|
@@ -24,6 +28,7 @@ module.exports = (moves, fen = initial, depth = 1) => {
|
|
|
24
28
|
from: item.from,
|
|
25
29
|
to: item.to,
|
|
26
30
|
comment: chess.getComment(),
|
|
31
|
+
suffix: chess.getSuffixAnnotation(),
|
|
27
32
|
fen: chess.fen(),
|
|
28
33
|
});
|
|
29
34
|
});
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chess-moments",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "PGN parser that transforms PGN files into chess \"moments\"",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"chess.js": "
|
|
27
|
+
"chess.js": "github:jhlywa/chess.js#master"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"chai": "^4.3.7",
|