@lichess-org/chessground 9.3.1 → 9.4.1

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/src/util.ts CHANGED
@@ -2,9 +2,7 @@ import * as cg from './types.js';
2
2
 
3
3
  export const invRanks: readonly cg.Rank[] = [...cg.ranks].reverse();
4
4
 
5
- export const allKeys: readonly cg.Key[] = Array.prototype.concat(
6
- ...cg.files.map(c => cg.ranks.map(r => c + r)),
7
- );
5
+ export const allKeys: readonly cg.Key[] = cg.files.flatMap(f => cg.ranks.map(r => (f + r) as cg.Key));
8
6
 
9
7
  export const pos2key = (pos: cg.Pos): cg.Key => allKeys[8 * pos[0] + pos[1]];
10
8
 
@@ -50,15 +48,14 @@ export const timer = (): cg.Timer => {
50
48
 
51
49
  export const opposite = (c: cg.Color): cg.Color => (c === 'white' ? 'black' : 'white');
52
50
 
53
- export const distanceSq = (pos1: cg.Pos, pos2: cg.Pos): number => {
54
- const dx = pos1[0] - pos2[0],
55
- dy = pos1[1] - pos2[1];
56
- return dx * dx + dy * dy;
57
- };
51
+ export const distanceSq = (pos1: cg.Pos, pos2: cg.Pos): number =>
52
+ (pos1[0] - pos2[0]) ** 2 + (pos1[1] - pos2[1]) ** 2;
58
53
 
59
54
  export const samePiece = (p1: cg.Piece, p2: cg.Piece): boolean =>
60
55
  p1.role === p2.role && p1.color === p2.color;
61
56
 
57
+ export const samePos = (p1: cg.Pos, p2: cg.Pos): boolean => p1[0] === p2[0] && p1[1] === p2[1];
58
+
62
59
  export const posToTranslate =
63
60
  (bounds: DOMRectReadOnly): ((pos: cg.Pos, asWhite: boolean) => cg.NumberPair) =>
64
61
  (pos, asWhite) => [
@@ -106,20 +103,32 @@ export function computeSquareCenter(key: cg.Key, asWhite: boolean, bounds: DOMRe
106
103
 
107
104
  export const diff = (a: number, b: number): number => Math.abs(a - b);
108
105
 
109
- export const knightDir: cg.DirectionalCheck = (x1, y1, x2, y2) => {
110
- const xd = diff(x1, x2);
111
- const yd = diff(y1, y2);
112
- return (xd === 1 && yd === 2) || (xd === 2 && yd === 1);
113
- };
106
+ export const knightDir: cg.DirectionalCheck = (x1, y1, x2, y2) => diff(x1, x2) * diff(y1, y2) === 2;
114
107
 
115
- export const rookDir: cg.DirectionalCheck = (x1, y1, x2, y2) => x1 === x2 || y1 === y2;
108
+ export const rookDir: cg.DirectionalCheck = (x1, y1, x2, y2) => (x1 === x2) !== (y1 === y2);
116
109
 
117
- export const bishopDir: cg.DirectionalCheck = (x1, y1, x2, y2) => diff(x1, x2) === diff(y1, y2);
110
+ export const bishopDir: cg.DirectionalCheck = (x1, y1, x2, y2) => diff(x1, x2) === diff(y1, y2) && x1 !== x2;
118
111
 
119
112
  export const queenDir: cg.DirectionalCheck = (x1, y1, x2, y2) =>
120
113
  rookDir(x1, y1, x2, y2) || bishopDir(x1, y1, x2, y2);
121
114
 
122
- /** Return all board squares between (x1, y1) and (x2, y2) exclusive,
115
+ export const kingDirNonCastling: cg.DirectionalCheck = (x1, y1, x2, y2) =>
116
+ Math.max(diff(x1, x2), diff(y1, y2)) === 1;
117
+
118
+ export const pawnDirCapture = (x1: number, y1: number, x2: number, y2: number, isDirectionUp: boolean) =>
119
+ diff(x1, x2) === 1 && y2 === y1 + (isDirectionUp ? 1 : -1);
120
+
121
+ export const pawnDirAdvance = (x1: number, y1: number, x2: number, y2: number, isDirectionUp: boolean) => {
122
+ const step = isDirectionUp ? 1 : -1;
123
+ return (
124
+ x1 === x2 &&
125
+ (y2 === y1 + step ||
126
+ // allow 2 squares from first two ranks, for horde
127
+ (y2 === y1 + 2 * step && (isDirectionUp ? y1 <= 1 : y1 >= 6)))
128
+ );
129
+ };
130
+
131
+ /** Returns all board squares between (x1, y1) and (x2, y2) exclusive,
123
132
  * along a straight line (rook or bishop path). Returns [] if not aligned, or none between.
124
133
  */
125
134
  export const squaresBetween = (x1: number, y1: number, x2: number, y2: number): cg.Key[] => {
@@ -129,10 +138,8 @@ export const squaresBetween = (x1: number, y1: number, x2: number, y2: number):
129
138
  // Must be a straight or diagonal line
130
139
  if (dx && dy && Math.abs(dx) !== Math.abs(dy)) return [];
131
140
 
132
- // Determine step direction
133
- const stepX = dx === 0 ? 0 : dx > 0 ? 1 : -1;
134
- const stepY = dy === 0 ? 0 : dy > 0 ? 1 : -1;
135
-
141
+ const stepX = Math.sign(dx),
142
+ stepY = Math.sign(dy);
136
143
  const squares: cg.Pos[] = [];
137
144
  let x = x1 + stepX,
138
145
  y = y1 + stepY;
@@ -143,3 +150,17 @@ export const squaresBetween = (x1: number, y1: number, x2: number, y2: number):
143
150
  }
144
151
  return squares.map(sq => pos2key(sq));
145
152
  };
153
+
154
+ export const adjacentSquares = (square: cg.Key): cg.Key[] => {
155
+ const pos = key2pos(square);
156
+ const adjacentSquares: cg.Pos[] = [];
157
+ if (pos[0] > 0) adjacentSquares.push([pos[0] - 1, pos[1]]);
158
+ if (pos[0] < 7) adjacentSquares.push([pos[0] + 1, pos[1]]);
159
+ return adjacentSquares.map(pos2key);
160
+ };
161
+
162
+ export const squareShiftedVertically = (square: cg.Key, delta: number): cg.Key => {
163
+ const pos = key2pos(square);
164
+ pos[1] += delta;
165
+ return pos2key(pos);
166
+ };