chess-moments 1.2.0 → 1.2.2

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,4 +1,4 @@
1
- const { getMoveNumber } = require('../helpers');
1
+ const { isNextFen } = require('../helpers');
2
2
 
3
3
  /**
4
4
  * Always returns an array because there can be more than one next moment
@@ -23,81 +23,41 @@ const getNextMoments = (moments, current) => {
23
23
  }
24
24
 
25
25
  // Last move of a sideline should not have any next moves
26
- if (
27
- !nextMoment?.move &&
28
- current.depth >= nextMoment.depth &&
29
- getMoveNumber(nextMoment.fen) <= getMoveNumber(current.fen)
30
- ) {
26
+ if (!nextMoment?.move && current.depth >= nextMoment.depth) {
31
27
  return [];
32
28
  }
33
29
 
34
- // Add the next moment if it has a move and is at the same depth
35
- if (nextMoment.move && current.depth === nextMoment.depth) {
36
- next.push(nextMoment);
37
- }
38
-
39
- // Return early if we have consecutive moves or no next next moment
40
- if (!nextNextMoment || (nextMoment?.move && nextNextMoment?.move)) {
41
- return next;
42
- }
43
-
44
- // Second to last move of a sideline should not have any next moves
30
+ // Return early if there are two consecutive moves at the same depth or if the next next move does not exist
45
31
  if (
46
- nextMoment?.move &&
47
- !nextNextMoment?.move &&
48
- current.depth >= nextNextMoment.depth &&
49
- getMoveNumber(nextNextMoment.fen) <= getMoveNumber(current.fen)
32
+ current.move &&
33
+ current.depth === nextMoment.depth &&
34
+ (!nextNextMoment || current.depth === nextNextMoment.depth)
50
35
  ) {
51
- return next;
52
- }
53
-
54
- // Remove all next moments until depth equals current.depth when next moment does not have a move
55
- if (!nextMoment?.move) {
56
- const filteredMoments = moments.filter((moment, index) => {
57
- return index <= nextIndex || moment.depth === current.depth;
58
- });
59
- moments = filteredMoments;
36
+ return [nextMoment];
60
37
  }
61
38
 
62
- // Add fullmove number to the current moment
63
- current.fullmove = Number(current.fen.split(' ')[5]);
39
+ // Remove all moves before the current moment
40
+ moments = moments.filter((moment) => moment.index > current.index);
64
41
 
65
- // Keep only slim moments
66
- const slim = moments.filter((moment) => {
67
- const fullmove = Number(moment.fen.split(' ')[5]);
68
- return (
69
- moment.index > current.index + 1 &&
70
- fullmove <= current.fullmove + 1 &&
71
- moment.move // Also filter out moments without a move
72
- );
73
- });
74
-
75
- // Active color after current move (who moves next)
76
- const activeColorAfterCurrent = current.fen.split(' ')[1];
77
-
78
- for (const moment of slim) {
79
- // Only process main line and immediate variations
80
- // Ignore next moments with depth lower than the current moment
81
- if (moment.depth > current.depth + 1 || moment.depth < current.depth) {
82
- continue;
42
+ // Remove all moments after the first moment that have a lower depth than the current moment
43
+ let filteredMoments = [];
44
+ for (const moment of moments) {
45
+ if (moment.depth < current.depth) {
46
+ break;
83
47
  }
48
+ filteredMoments.push(moment);
49
+ }
84
50
 
85
- const activeColorAfterMoment = moment.fen.split(' ')[1];
86
- const fullmove = Number(moment.fen.split(' ')[5]);
87
-
88
- // Check if this is a valid next move based on color and fullmove
89
- const isValidWhiteMove =
90
- activeColorAfterCurrent === 'w' &&
91
- activeColorAfterMoment === 'b' &&
92
- fullmove === current.fullmove;
93
-
94
- const isValidBlackMove =
95
- activeColorAfterCurrent === 'b' &&
96
- activeColorAfterMoment === 'w' &&
97
- fullmove === current.fullmove + 1;
51
+ // If next moment does not have a move, remove all moments with the depth higher than current depth
52
+ if (!nextMoment.move) {
53
+ filteredMoments = filteredMoments.filter(
54
+ (moment) => moment.depth <= current.depth
55
+ );
56
+ }
98
57
 
99
- // If the move is valid, add it to the next moments
100
- if (isValidWhiteMove || isValidBlackMove) {
58
+ // Finally check for next moments from filtered moments
59
+ for (const moment of filteredMoments) {
60
+ if (moment.move && isNextFen(current.fen, moment.fen)) {
101
61
  next.push(moment);
102
62
  }
103
63
  }
@@ -2,6 +2,7 @@ const getBrushCode = require('./get-brush-code');
2
2
  const getBrushColor = require('./get-brush-color');
3
3
  const getMoveNumber = require('./get-move-number');
4
4
  const insertMomentIntoTree = require('./insert-moment-into-tree');
5
+ const isNextFen = require('./is-next-fen');
5
6
  const prepareMoment = require('./prepare-moment');
6
7
 
7
8
  module.exports = {
@@ -9,5 +10,6 @@ module.exports = {
9
10
  getBrushColor,
10
11
  getMoveNumber,
11
12
  insertMomentIntoTree,
13
+ isNextFen,
12
14
  prepareMoment,
13
15
  };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Determines if nextFen comes immediately after currentFen in a chess game
3
+ *
4
+ * @param {String} currentFen - The current FEN position
5
+ * @param {String} nextFen - The potential next FEN position
6
+ * @returns {Boolean} - True if nextFen comes immediately after currentFen
7
+ */
8
+ const isNextFen = (currentFen, nextFen) => {
9
+ try {
10
+ // Parse FEN components
11
+ const currentParts = currentFen.split(' ');
12
+ const nextParts = nextFen.split(' ');
13
+
14
+ // Validate FEN format (should have 6 parts each)
15
+ if (currentParts.length !== 6 || nextParts.length !== 6) {
16
+ return false;
17
+ }
18
+
19
+ const currentActiveColor = currentParts[1]; // 'w' or 'b' - who moves in current position
20
+ const currentFullmove = Number(currentParts[5]);
21
+
22
+ const nextActiveColor = nextParts[1]; // 'w' or 'b' - who moves in next position
23
+ const nextFullmove = Number(nextParts[5]);
24
+
25
+ // Check if the active color and fullmove number progression is valid
26
+ if (currentActiveColor === 'w') {
27
+ // If white is to move in current position, then after white's move:
28
+ // - Black should be to move in next position
29
+ // - Fullmove number should remain the same
30
+ return nextActiveColor === 'b' && nextFullmove === currentFullmove;
31
+ } else {
32
+ // If black is to move in current position, then after black's move:
33
+ // - White should be to move in next position
34
+ // - Fullmove number should increment by 1
35
+ return nextActiveColor === 'w' && nextFullmove === currentFullmove + 1;
36
+ }
37
+ } catch (error) {
38
+ return false;
39
+ }
40
+ };
41
+
42
+ module.exports = isNextFen;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chess-moments",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "PGN parser that transforms PGN files into chess \"moments\"",
5
5
  "main": "index.js",
6
6
  "files": [