chess-tactics 0.0.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.
Files changed (43) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +145 -0
  3. package/dist/ChessTactics.d.ts +8 -0
  4. package/dist/ChessTactics.js +37 -0
  5. package/dist/TacticFactory.d.ts +4 -0
  6. package/dist/TacticFactory.js +25 -0
  7. package/dist/_types.d.ts +15 -0
  8. package/dist/_types.js +2 -0
  9. package/dist/errors.d.ts +7 -0
  10. package/dist/errors.js +12 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +23 -0
  13. package/dist/tactics/BaseTactic.d.ts +13 -0
  14. package/dist/tactics/BaseTactic.js +68 -0
  15. package/dist/tactics/Fork.d.ts +9 -0
  16. package/dist/tactics/Fork.js +32 -0
  17. package/dist/tactics/HangingPiece.d.ts +7 -0
  18. package/dist/tactics/HangingPiece.js +34 -0
  19. package/dist/tactics/Pin.d.ts +10 -0
  20. package/dist/tactics/Pin.js +97 -0
  21. package/dist/tactics/Sacrifice.d.ts +9 -0
  22. package/dist/tactics/Sacrifice.js +41 -0
  23. package/dist/tactics/Skewer.d.ts +9 -0
  24. package/dist/tactics/Skewer.js +81 -0
  25. package/dist/tactics/Trap.d.ts +12 -0
  26. package/dist/tactics/Trap.js +100 -0
  27. package/dist/tactics/index.d.ts +7 -0
  28. package/dist/tactics/index.js +17 -0
  29. package/dist/types.d.ts +46 -0
  30. package/dist/types.js +2 -0
  31. package/dist/utils/SequenceInterpreter.d.ts +13 -0
  32. package/dist/utils/SequenceInterpreter.js +88 -0
  33. package/dist/utils/TacticContextParser.d.ts +9 -0
  34. package/dist/utils/TacticContextParser.js +109 -0
  35. package/dist/utils/TacticHeuristics.d.ts +9 -0
  36. package/dist/utils/TacticHeuristics.js +177 -0
  37. package/dist/utils/Utils.d.ts +18 -0
  38. package/dist/utils/Utils.js +106 -0
  39. package/dist/utils/constants.d.ts +5 -0
  40. package/dist/utils/constants.js +22 -0
  41. package/dist/utils/index.d.ts +5 -0
  42. package/dist/utils/index.js +24 -0
  43. package/package.json +28 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SkewerTactics = void 0;
4
+ const chess_js_1 = require("chess.js");
5
+ const _utils_1 = require("../utils/index");
6
+ const _tactics_1 = require("./index");
7
+ class SkewerTactics extends _tactics_1.BaseTactic {
8
+ isTactic(context) {
9
+ const { position, evaluation } = context;
10
+ const chess = new chess_js_1.Chess(position);
11
+ const currentMove = chess.move(evaluation.sequence[0]);
12
+ const cosmeticSkewers = this.getCosmeticSkewers(context);
13
+ for (const [nextMoveWithPiece, nextMoveWithoutPiece] of cosmeticSkewers) {
14
+ const tacticalSequence = this.sequenceInterpreter.identifyWinningSequence([currentMove.to], [nextMoveWithPiece.to, nextMoveWithoutPiece.to]);
15
+ if (tacticalSequence) {
16
+ return {
17
+ type: "skewer",
18
+ attackedPieces: [
19
+ { square: nextMoveWithPiece.to, piece: chess.get(nextMoveWithPiece.to) },
20
+ {
21
+ square: nextMoveWithoutPiece.to,
22
+ piece: chess.get(nextMoveWithoutPiece.to),
23
+ },
24
+ ],
25
+ ...tacticalSequence,
26
+ };
27
+ }
28
+ }
29
+ return null;
30
+ }
31
+ getCosmeticSkewers(context) {
32
+ const { evaluation, position } = context;
33
+ const currentMove = evaluation.sequence[0];
34
+ if (["p", "k", "n"].includes(currentMove.piece)) {
35
+ return [];
36
+ }
37
+ const chess = new chess_js_1.Chess(position);
38
+ chess.move(currentMove);
39
+ // On the next turn where can you move this piece
40
+ (0, _utils_1.invertTurn)(chess);
41
+ const possibleNextMoves = chess.moves({ square: currentMove.to, verbose: true });
42
+ const cosmeticSkewers = [];
43
+ for (const move of possibleNextMoves) {
44
+ if (!move.captured || move.captured === currentMove.piece) {
45
+ continue;
46
+ }
47
+ // Return to on next turn position and remove the piece
48
+ chess.load(position);
49
+ chess.move(currentMove);
50
+ if (move.captured === "k") {
51
+ if (evaluation.sequence.length === 1) {
52
+ return [];
53
+ }
54
+ const response = evaluation.sequence[1];
55
+ if (response.piece !== "k") {
56
+ return [];
57
+ }
58
+ chess.move(response);
59
+ }
60
+ else {
61
+ chess.remove(move.to);
62
+ (0, _utils_1.invertTurn)(chess);
63
+ }
64
+ const possibleNextMovesWithoutPiece = chess.moves({
65
+ square: currentMove.to,
66
+ verbose: true,
67
+ });
68
+ const newMoves = (0, _utils_1.getMoveDiff)(possibleNextMoves, possibleNextMovesWithoutPiece);
69
+ for (const m of newMoves) {
70
+ // can you capture behind the piece in front, and is the piece in front more valuable
71
+ if (m.captured &&
72
+ _utils_1.PIECE_VALUES[move.captured] > _utils_1.PIECE_VALUES[m.captured] &&
73
+ !(0, _utils_1.attackingSquareIsBad)(chess.fen(), m.to)) {
74
+ cosmeticSkewers.push([move, m]);
75
+ }
76
+ }
77
+ }
78
+ return cosmeticSkewers;
79
+ }
80
+ }
81
+ exports.SkewerTactics = SkewerTactics;
@@ -0,0 +1,12 @@
1
+ import { Move } from "chess.js";
2
+ import { Fen, Tactic } from "../types";
3
+ import { BaseTactic } from "./index";
4
+ import { _DefaultTacticContext } from "src/_types";
5
+ declare class TrapTactics extends BaseTactic {
6
+ isTactic(context: _DefaultTacticContext): Partial<Tactic> | null;
7
+ getCosmeticTrap(position: Fen, currentMove: Move): any | null;
8
+ private pieceIsTrapped;
9
+ private getCapturablePieces;
10
+ private piecePinnedToKing;
11
+ }
12
+ export { TrapTactics };
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrapTactics = void 0;
4
+ const chess_js_1 = require("chess.js");
5
+ const _utils_1 = require("../utils/index");
6
+ const _tactics_1 = require("./index");
7
+ class TrapTactics extends _tactics_1.BaseTactic {
8
+ isTactic(context) {
9
+ const { position, evaluation } = context;
10
+ const chess = new chess_js_1.Chess(position);
11
+ const currentMove = chess.move(evaluation.sequence[0]);
12
+ const cosmeticTrap = this.getCosmeticTrap(position, currentMove);
13
+ const tacticalSequence = this.sequenceInterpreter.identifyWinningSequence([currentMove.to], cosmeticTrap?.trappingSquares ?? []);
14
+ if (tacticalSequence) {
15
+ return {
16
+ type: "trap",
17
+ attackedPieces: [{ square: currentMove.to, piece: chess.get(currentMove.to) }],
18
+ ...tacticalSequence,
19
+ };
20
+ }
21
+ return null;
22
+ }
23
+ getCosmeticTrap(position, currentMove) {
24
+ const chess = new chess_js_1.Chess(position);
25
+ const capturingMoves = this.getCapturablePieces(currentMove, position);
26
+ // the position after currentMove is a check
27
+ if (capturingMoves.filter((m) => m.captured === "k").length > 0)
28
+ return null;
29
+ for (let i = 0; i < capturingMoves.length; i++) {
30
+ chess.load(position);
31
+ chess.move(currentMove);
32
+ const m = capturingMoves[i];
33
+ const fen = chess.fen();
34
+ if (this.pieceIsTrapped(fen, m)) {
35
+ if (m.captured && _utils_1.PIECE_VALUES[m.piece] < _utils_1.PIECE_VALUES[m.captured]) {
36
+ return {
37
+ trappedPiece: m.captured,
38
+ trappingSquares: chess
39
+ .moves({ square: m.to, verbose: true })
40
+ .map((s) => s.to)
41
+ .concat(m.to),
42
+ };
43
+ }
44
+ else {
45
+ // piece doesn't move. can we capture it?
46
+ const chessCopy = new chess_js_1.Chess(chess.fen());
47
+ (0, _utils_1.invertTurn)(chessCopy);
48
+ if ((0, _utils_1.attackingSquareIsGood)(chessCopy.fen(), m.to)) {
49
+ return {
50
+ trappedPiece: m.captured,
51
+ trappingSquares: chess
52
+ .moves({ square: m.to, verbose: true })
53
+ .map((s) => s.to)
54
+ .concat(m.to),
55
+ };
56
+ }
57
+ }
58
+ }
59
+ }
60
+ return null;
61
+ }
62
+ pieceIsTrapped(position, move) {
63
+ const attackingSquare = move.from;
64
+ const threatenedSquare = move.to;
65
+ const escapeSquares = (0, _utils_1.getEscapeSquares)(position, threatenedSquare);
66
+ const blockingMoves = (0, _utils_1.getBlockingMoves)(position, attackingSquare, threatenedSquare);
67
+ // can't trap a pawn, any pinned piece should not be a 'trap'
68
+ if (move.captured === "p" || this.piecePinnedToKing(position, move.to))
69
+ return false;
70
+ return escapeSquares.length === 0 && blockingMoves.length === 0;
71
+ }
72
+ getCapturablePieces(currentMove, position) {
73
+ // A capturable piece is one that can be taken. No other assumptions
74
+ // game must be the initial position
75
+ const chessCopy = new chess_js_1.Chess(position);
76
+ chessCopy.move(currentMove);
77
+ (0, _utils_1.invertTurn)(chessCopy);
78
+ const possibleMoves = chessCopy.moves({ verbose: true });
79
+ let targetedPieces = [];
80
+ for (const m of possibleMoves) {
81
+ if (m.captured) {
82
+ targetedPieces.push(m);
83
+ }
84
+ }
85
+ return targetedPieces;
86
+ }
87
+ piecePinnedToKing(fen, square) {
88
+ const chess = new chess_js_1.Chess(fen);
89
+ const color = chess.get(square)?.color;
90
+ const parts = fen.split(" ");
91
+ fen = parts[0] + " " + color + " " + parts.slice(2).join(" ");
92
+ chess.load(fen, { skipValidation: true });
93
+ if (chess.inCheck()) {
94
+ return false;
95
+ }
96
+ chess.remove(square);
97
+ return chess.inCheck();
98
+ }
99
+ }
100
+ exports.TrapTactics = TrapTactics;
@@ -0,0 +1,7 @@
1
+ export { BaseTactic } from "./BaseTactic";
2
+ export { ForkTactics } from "./Fork";
3
+ export { HangingPieceTactics } from "./HangingPiece";
4
+ export { PinTactics } from "./Pin";
5
+ export { SacrificeTactics } from "./Sacrifice";
6
+ export { SkewerTactics } from "./Skewer";
7
+ export { TrapTactics } from "./Trap";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrapTactics = exports.SkewerTactics = exports.SacrificeTactics = exports.PinTactics = exports.HangingPieceTactics = exports.ForkTactics = exports.BaseTactic = void 0;
4
+ var BaseTactic_1 = require("./BaseTactic");
5
+ Object.defineProperty(exports, "BaseTactic", { enumerable: true, get: function () { return BaseTactic_1.BaseTactic; } });
6
+ var Fork_1 = require("./Fork");
7
+ Object.defineProperty(exports, "ForkTactics", { enumerable: true, get: function () { return Fork_1.ForkTactics; } });
8
+ var HangingPiece_1 = require("./HangingPiece");
9
+ Object.defineProperty(exports, "HangingPieceTactics", { enumerable: true, get: function () { return HangingPiece_1.HangingPieceTactics; } });
10
+ var Pin_1 = require("./Pin");
11
+ Object.defineProperty(exports, "PinTactics", { enumerable: true, get: function () { return Pin_1.PinTactics; } });
12
+ var Sacrifice_1 = require("./Sacrifice");
13
+ Object.defineProperty(exports, "SacrificeTactics", { enumerable: true, get: function () { return Sacrifice_1.SacrificeTactics; } });
14
+ var Skewer_1 = require("./Skewer");
15
+ Object.defineProperty(exports, "SkewerTactics", { enumerable: true, get: function () { return Skewer_1.SkewerTactics; } });
16
+ var Trap_1 = require("./Trap");
17
+ Object.defineProperty(exports, "TrapTactics", { enumerable: true, get: function () { return Trap_1.TrapTactics; } });
@@ -0,0 +1,46 @@
1
+ import { Move, Piece, Square } from "chess.js";
2
+ import { _TacticContext } from "./_types";
3
+ export type Fen = string;
4
+ export type TacticOptions = {
5
+ trimEndSequence?: boolean;
6
+ };
7
+ export type UciEvaluation = {
8
+ sequence: string | string[] | Move[];
9
+ };
10
+ export type MoveEvaluation = {
11
+ move: string | {
12
+ from: string;
13
+ to: string;
14
+ } | Move;
15
+ followup: string | string[] | Move[];
16
+ };
17
+ export type Evaluation = UciEvaluation | MoveEvaluation;
18
+ export type DefaultTacticContext = {
19
+ position: Fen;
20
+ evaluation: Evaluation;
21
+ };
22
+ export type PositionComparisonTacticContext = DefaultTacticContext & {
23
+ prevEvaluation: Evaluation;
24
+ prevMove: Move;
25
+ prevPosition: Fen;
26
+ };
27
+ export type TacticContext = DefaultTacticContext | PositionComparisonTacticContext;
28
+ export type TacticKey = "fork" | "pin" | "skewer" | "sacrifice" | "trap" | "hanging";
29
+ export interface TacticClassifier {
30
+ findTactic(context: _TacticContext): Tactic | null;
31
+ isTactic(context: _TacticContext): Partial<Tactic> | null;
32
+ }
33
+ export type SequenceInterpretation = {
34
+ sequence: Move[];
35
+ startPosition: Fen;
36
+ endPosition: Fen;
37
+ materialChange: number;
38
+ };
39
+ export type Tactic = SequenceInterpretation & {
40
+ type: TacticKey;
41
+ triggerIndex: number;
42
+ attackedPieces: {
43
+ square: Square;
44
+ piece: Piece;
45
+ }[];
46
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import { Fen, SequenceInterpretation } from "../types";
2
+ import { Move, Square } from "chess.js";
3
+ import { _TacticContext } from "src/_types";
4
+ export declare class SequenceInterpreter {
5
+ private evaluation;
6
+ private position;
7
+ setContext(context: _TacticContext): void;
8
+ getCaptureSequence(position: Fen, sequence: Move[]): any[];
9
+ identifyWinningSequence(attackerSquares: Square[], attackedSquares: Square[]): SequenceInterpretation | null;
10
+ private capturedAttackedPieces;
11
+ private isDesparado;
12
+ positionAfterSequence(position: Fen, sequence: string[] | Move[] | null): string;
13
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SequenceInterpreter = void 0;
4
+ const chess_js_1 = require("chess.js");
5
+ const _utils_1 = require("./index");
6
+ class SequenceInterpreter {
7
+ evaluation;
8
+ position;
9
+ setContext(context) {
10
+ const { evaluation, position } = context;
11
+ this.evaluation = evaluation;
12
+ this.position = position;
13
+ }
14
+ getCaptureSequence(position, sequence) {
15
+ const chess = new chess_js_1.Chess(position);
16
+ const matches = [];
17
+ for (const s of sequence) {
18
+ const prevChess = new chess_js_1.Chess(chess.fen());
19
+ const m = chess.move(s);
20
+ if (m.captured || chess.inCheck() || prevChess.inCheck()) {
21
+ matches.push(m.san);
22
+ }
23
+ else {
24
+ break;
25
+ }
26
+ }
27
+ return matches;
28
+ }
29
+ // either the pieces on attackedSquares are captured for material gain
30
+ // or defender desparados on attackerSquare for a loss of material
31
+ // the separation of tacticalSequence and remainingSequence
32
+ // is to ensure that non-capturing engine intermezzos
33
+ // still allow captures on attackedSquares to be found
34
+ identifyWinningSequence(attackerSquares, attackedSquares) {
35
+ if (attackedSquares.length === 0 || attackerSquares.length === 0)
36
+ return null;
37
+ let tacticalSequence = [];
38
+ const chess = new chess_js_1.Chess(this.position);
39
+ const moves = this.evaluation.sequence;
40
+ for (let i = 0; i < moves.length; i++) {
41
+ const move = moves[i];
42
+ tacticalSequence.push(move);
43
+ const position = chess.fen();
44
+ chess.move(move);
45
+ if (this.capturedAttackedPieces(move, attackerSquares, attackedSquares) ||
46
+ this.isDesparado(position, move)) {
47
+ const remainingSequence = moves.slice(i + 1);
48
+ tacticalSequence = tacticalSequence.concat(this.getCaptureSequence(chess.fen(), remainingSequence));
49
+ const endPosition = this.positionAfterSequence(this.position, tacticalSequence);
50
+ const materialChange = (0, _utils_1.getMaterialChange)(position, endPosition, (0, _utils_1.colorToPlay)(this.position));
51
+ if (materialChange > 0) {
52
+ return {
53
+ startPosition: this.position,
54
+ endPosition: endPosition,
55
+ sequence: tacticalSequence,
56
+ materialChange: materialChange,
57
+ };
58
+ }
59
+ else {
60
+ return null;
61
+ }
62
+ }
63
+ }
64
+ return null;
65
+ }
66
+ capturedAttackedPieces(move, attackerSquares, attackedSquares) {
67
+ const capturedSquares = attackedSquares.filter((s) => {
68
+ // move came from an attacker square, to an attackedSquare, and captured a piece
69
+ return s === move.to && move.captured;
70
+ });
71
+ return capturedSquares.length > 0;
72
+ }
73
+ isDesparado(position, move) {
74
+ if (!move.captured)
75
+ return false;
76
+ return (0, _utils_1.attackingSquareIsBad)(position, move.to);
77
+ }
78
+ positionAfterSequence(position, sequence) {
79
+ if (!sequence)
80
+ return position;
81
+ const chess = new chess_js_1.Chess(position);
82
+ sequence.forEach((m) => {
83
+ chess.move(m);
84
+ });
85
+ return chess.fen();
86
+ }
87
+ }
88
+ exports.SequenceInterpreter = SequenceInterpreter;
@@ -0,0 +1,9 @@
1
+ import { Evaluation, Fen, MoveEvaluation, TacticContext, TacticOptions, UciEvaluation } from "../types";
2
+ import { _Evaluation, _TacticContext } from "src/_types";
3
+ export declare class TacticContextParser {
4
+ static parse(context: TacticContext, options: TacticOptions): _TacticContext;
5
+ static parseEvaluation(position: Fen, evaluation: Evaluation, options: TacticOptions): _Evaluation;
6
+ private static trimEndCaptures;
7
+ static parseMoveEvaluation(position: Fen, evaluation: MoveEvaluation): _Evaluation;
8
+ static parseUciEvaluation(position: Fen, evaluation: UciEvaluation): _Evaluation;
9
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TacticContextParser = void 0;
4
+ const chess_js_1 = require("chess.js");
5
+ const _chess_tactics_1 = require("..");
6
+ class TacticContextParser {
7
+ static parse(context, options) {
8
+ const evaluation = this.parseEvaluation(context.position, context.evaluation, options);
9
+ if ("prevEvaluation" in context) {
10
+ const prevEvaluation = this.parseEvaluation(context.prevPosition, context.prevEvaluation, options);
11
+ return {
12
+ evaluation: evaluation,
13
+ position: context.position,
14
+ prevEvaluation: prevEvaluation,
15
+ prevMove: context.prevMove,
16
+ prevPosition: context.prevPosition,
17
+ };
18
+ }
19
+ return {
20
+ evaluation: evaluation,
21
+ position: context.position,
22
+ };
23
+ }
24
+ static parseEvaluation(position, evaluation, options) {
25
+ let parsedEvaluation;
26
+ if ("sequence" in evaluation) {
27
+ parsedEvaluation = this.parseUciEvaluation(position, evaluation);
28
+ }
29
+ else {
30
+ parsedEvaluation = this.parseMoveEvaluation(position, evaluation);
31
+ }
32
+ if (options.trimEndSequence) {
33
+ parsedEvaluation.sequence = this.trimEndCaptures(parsedEvaluation.sequence);
34
+ }
35
+ return parsedEvaluation;
36
+ }
37
+ static trimEndCaptures(moveList) {
38
+ let i = moveList.length - 1;
39
+ while (i >= 0) {
40
+ if (moveList[i].captured) {
41
+ i -= 1;
42
+ }
43
+ else {
44
+ break;
45
+ }
46
+ }
47
+ return moveList.slice(0, i + 1);
48
+ }
49
+ static parseMoveEvaluation(position, evaluation) {
50
+ let chess;
51
+ try {
52
+ chess = new chess_js_1.Chess(position);
53
+ }
54
+ catch (error) {
55
+ throw new _chess_tactics_1.ChessTacticsParserError(`Invalid position argument: ${position}`, "INVALID_FEN", { cause: error });
56
+ }
57
+ const sequence = Array.isArray(evaluation.followup)
58
+ ? evaluation.followup
59
+ : evaluation.followup.split(/\s+/).filter((m) => m);
60
+ let firstMove;
61
+ try {
62
+ firstMove = chess.move(evaluation.move);
63
+ }
64
+ catch (error) {
65
+ throw new _chess_tactics_1.ChessTacticsParserError(`Invalid move: ${JSON.stringify(evaluation.move)} is not playable in ${position}`, "INVALID_MOVE", { cause: error });
66
+ }
67
+ const moveList = [firstMove];
68
+ let currPos;
69
+ sequence.forEach((s) => {
70
+ try {
71
+ currPos = chess.fen();
72
+ moveList.push(chess.move(s));
73
+ }
74
+ catch (error) {
75
+ throw new _chess_tactics_1.ChessTacticsParserError(`Invalid followup: ${JSON.stringify(s)} is not playable in ${currPos}`, "INVALID_FOLLOWUP", { cause: error });
76
+ }
77
+ });
78
+ return {
79
+ sequence: moveList,
80
+ };
81
+ }
82
+ static parseUciEvaluation(position, evaluation) {
83
+ let chess;
84
+ try {
85
+ chess = new chess_js_1.Chess(position);
86
+ }
87
+ catch (error) {
88
+ throw new _chess_tactics_1.ChessTacticsParserError(`Invalid position argument: ${position}`, "INVALID_FEN", { cause: error });
89
+ }
90
+ const moveList = [];
91
+ const sequence = Array.isArray(evaluation.sequence)
92
+ ? evaluation.sequence
93
+ : evaluation.sequence.split(/\s+/).filter((m) => m);
94
+ let currPos;
95
+ sequence.forEach((s) => {
96
+ try {
97
+ currPos = chess.fen();
98
+ moveList.push(chess.move(s));
99
+ }
100
+ catch (error) {
101
+ throw new _chess_tactics_1.ChessTacticsParserError(`Invalid sequence: ${JSON.stringify(s)} is not playable in ${currPos}`, "INVALID_SEQUENCE", { cause: error });
102
+ }
103
+ });
104
+ return {
105
+ sequence: moveList,
106
+ };
107
+ }
108
+ }
109
+ exports.TacticContextParser = TacticContextParser;
@@ -0,0 +1,9 @@
1
+ import { Fen } from "../types";
2
+ import { Move, Square } from "chess.js";
3
+ export declare function attackingSquareIsGood(fen: Fen, square: Square, startingMove?: Move): boolean;
4
+ export declare function attackingSquareIsBad(fen: Fen, square: Square, startingMove?: Move): boolean;
5
+ export declare function materialAdvantageAfterTradesAtSquare(position: Fen, square: Square, startingMove?: Move): number;
6
+ export declare function getEscapeSquares(fen: Fen, square: Square): any[];
7
+ export declare function getBlockingMoves(fen: Fen, attackingSquare: Square, threatenedSquare: Square): any[];
8
+ export declare function getMovesToSquare(fen: Fen, square: Square): Move[];
9
+ export declare function getThreateningMoves(position: Fen, currentMove: Move): Move[];