fix: tests and attacked squares

This commit is contained in:
Cozma Rares
2023-05-01 02:37:43 +03:00
parent 77c58eae1e
commit 83fefbc71a
3 changed files with 193 additions and 125 deletions
+162 -106
View File
@@ -28,8 +28,17 @@ function runTest(fen: string, expectedMoves: ExpectedMoves) {
);
}
function runTests(
fen: string,
expectedMovesW: ExpectedMoves,
expectedMovesB: ExpectedMoves
) {
runTest(fen.replace("%", "w"), expectedMovesW);
runTest(fen.replace("%", "b"), expectedMovesB);
}
describe("pawn moves", () => {
const expectedMoves: ExpectedMoves = {
const expectedMovesW: ExpectedMoves = {
can_jump: [
{
square: "a2",
@@ -38,13 +47,6 @@ describe("pawn moves", () => {
{ from: "a2", to: "a4", flag: MOVE_FLAGS.PAWN_JUMP },
],
},
{
square: "h7",
moves: [
{ from: "h7", to: "h6", flag: MOVE_FLAGS.NORMAL },
{ from: "h7", to: "h5", flag: MOVE_FLAGS.PAWN_JUMP },
],
},
],
promotion: [
{
@@ -56,6 +58,41 @@ describe("pawn moves", () => {
{ from: "b7", to: "b8", flag: MOVE_FLAGS.PROMOTION, promotion: "q" },
],
},
],
regular: [
{
square: "c3",
moves: [{ from: "c3", to: "c4", flag: MOVE_FLAGS.NORMAL }],
},
],
attack: [
{
square: "d4",
moves: [
{ from: "d4", to: "d5", flag: MOVE_FLAGS.NORMAL },
{ from: "d4", to: "e5", flag: MOVE_FLAGS.CAPTURE },
],
},
],
blocked: [
{
square: "c6",
moves: [],
},
],
};
const expectedMovesB: ExpectedMoves = {
can_jump: [
{
square: "h7",
moves: [
{ from: "h7", to: "h6", flag: MOVE_FLAGS.NORMAL },
{ from: "h7", to: "h5", flag: MOVE_FLAGS.PAWN_JUMP },
],
},
],
promotion: [
{
square: "g2",
moves: [
@@ -67,23 +104,12 @@ describe("pawn moves", () => {
},
],
regular: [
{
square: "c3",
moves: [{ from: "c3", to: "c4", flag: MOVE_FLAGS.NORMAL }],
},
{
square: "f6",
moves: [{ from: "f6", to: "f5", flag: MOVE_FLAGS.NORMAL }],
},
],
attack: [
{
square: "d4",
moves: [
{ from: "d4", to: "d5", flag: MOVE_FLAGS.NORMAL },
{ from: "d4", to: "e5", flag: MOVE_FLAGS.CAPTURE },
],
},
{
square: "e5",
moves: [
@@ -97,10 +123,7 @@ describe("pawn moves", () => {
square: "c7",
moves: [],
},
{
square: "c6",
moves: [],
},
{
square: "e7",
moves: [{ from: "e7", to: "e6", flag: MOVE_FLAGS.NORMAL }],
@@ -108,31 +131,15 @@ describe("pawn moves", () => {
],
};
runTest("7k/1Pp1p2p/2P2p2/4p3/3P4/2P5/P5p1/K7 w - - 0 1", expectedMoves);
runTests(
"7k/1Pp1p2p/2P2p2/4p3/3P4/2P5/P5p1/K7 % - - 0 1",
expectedMovesW,
expectedMovesB
);
});
describe("knight moves", () => {
const expectedMoves: ExpectedMoves = {
exclude_a: [
{
square: "a8",
moves: [
{ from: "a8", to: "b6", flag: MOVE_FLAGS.NORMAL },
{ from: "a8", to: "c7", flag: MOVE_FLAGS.NORMAL },
],
},
],
exclude_b: [
{
square: "b7",
moves: [
{ from: "b7", to: "a5", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "c5", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "d6", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "d8", flag: MOVE_FLAGS.NORMAL },
],
},
],
const expectedMovesW: ExpectedMoves = {
exclude_g: [
{
square: "g2",
@@ -162,18 +169,6 @@ describe("knight moves", () => {
{ from: "a2", to: "b4", flag: MOVE_FLAGS.NORMAL },
],
},
{
square: "c3",
moves: [
{ from: "c3", to: "e4", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "b5", flag: MOVE_FLAGS.CAPTURE },
{ from: "c3", to: "a4", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "a2", flag: MOVE_FLAGS.CAPTURE },
{ from: "c3", to: "b1", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "d1", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "e2", flag: MOVE_FLAGS.NORMAL },
],
},
],
regular: [
{
@@ -192,11 +187,53 @@ describe("knight moves", () => {
],
};
runTest("n7/1n6/8/1K1kN3/8/2n5/N5N1/7N w - - 0 1", expectedMoves);
const expectedMovesB: ExpectedMoves = {
exclude_a: [
{
square: "a8",
moves: [
{ from: "a8", to: "b6", flag: MOVE_FLAGS.NORMAL },
{ from: "a8", to: "c7", flag: MOVE_FLAGS.NORMAL },
],
},
],
exclude_b: [
{
square: "b7",
moves: [
{ from: "b7", to: "a5", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "c5", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "d6", flag: MOVE_FLAGS.NORMAL },
{ from: "b7", to: "d8", flag: MOVE_FLAGS.NORMAL },
],
},
],
attack: [
{
square: "c3",
moves: [
{ from: "c3", to: "e4", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "b5", flag: MOVE_FLAGS.CAPTURE },
{ from: "c3", to: "a4", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "a2", flag: MOVE_FLAGS.CAPTURE },
{ from: "c3", to: "b1", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "d1", flag: MOVE_FLAGS.NORMAL },
{ from: "c3", to: "e2", flag: MOVE_FLAGS.NORMAL },
],
},
],
};
runTests(
"n7/1n6/8/1K1kN3/8/2n5/N5N1/7N % - - 0 1",
expectedMovesW,
expectedMovesB
);
});
describe("bishop moves", () => {
const expectedMoves: ExpectedMoves = {
const expectedMovesW: ExpectedMoves = {
exclude_a: [
{
square: "a2",
@@ -211,20 +248,6 @@ describe("bishop moves", () => {
],
},
],
exclude_h: [
{
square: "h8",
moves: [
{ from: "h8", to: "g7", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "f6", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "e5", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "d4", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "c3", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "b2", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "a1", flag: MOVE_FLAGS.NORMAL },
],
},
],
attack: [
{
square: "d2",
@@ -239,6 +262,41 @@ describe("bishop moves", () => {
{ from: "d2", to: "g5", flag: MOVE_FLAGS.CAPTURE },
],
},
],
regular: [
{
square: "c2",
moves: [
{ from: "c2", to: "b1", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "d1", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "b3", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "a4", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "d3", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "e4", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "f5", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "g6", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "h7", flag: MOVE_FLAGS.NORMAL },
],
},
],
};
const expectedMovesB: ExpectedMoves = {
exclude_h: [
{
square: "h8",
moves: [
{ from: "h8", to: "g7", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "f6", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "e5", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "d4", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "c3", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "b2", flag: MOVE_FLAGS.NORMAL },
{ from: "h8", to: "a1", flag: MOVE_FLAGS.NORMAL },
],
},
],
attack: [
{
square: "g5",
moves: [
@@ -281,29 +339,17 @@ describe("bishop moves", () => {
],
},
],
regular: [
{
square: "c2",
moves: [
{ from: "c2", to: "b1", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "d1", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "b3", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "a4", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "d3", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "e4", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "f5", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "g6", flag: MOVE_FLAGS.NORMAL },
{ from: "c2", to: "h7", flag: MOVE_FLAGS.NORMAL },
],
},
],
};
runTest("K6b/8/3b4/2b3b1/8/8/B1BB4/7k w - - 0 1", expectedMoves);
runTests(
"K6b/8/3b4/2b3b1/8/8/B1BB4/7k % - - 0 1",
expectedMovesW,
expectedMovesB
);
});
describe("rook moves", () => {
const expectedMoves: ExpectedMoves = {
const expectedMovesW: ExpectedMoves = {
exclude_a: [
{
square: "a5",
@@ -325,6 +371,9 @@ describe("rook moves", () => {
],
},
],
};
const expectedMovesB: ExpectedMoves = {
exclude_h: [
{
square: "h2",
@@ -348,12 +397,12 @@ describe("rook moves", () => {
],
};
runTest("8/6K1/8/R7/8/8/7r/6k1 w - - 0 1", expectedMoves);
runTests("8/6K1/8/R7/8/8/7r/6k1 % - - 0 1", expectedMovesW, expectedMovesB);
});
describe("queen and king moves", () => {
const expectedMoves: ExpectedMoves = {
queen: [
const expectedMovesW: ExpectedMoves = {
white_queen: [
{
square: "h8",
moves: [
@@ -380,6 +429,23 @@ describe("queen and king moves", () => {
{ from: "h8", to: "a1", flag: MOVE_FLAGS.NORMAL },
],
},
],
white_king: [
{
square: "g3",
moves: [
{ from: "g3", to: "f3", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "f4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "g4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "h4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "h3", flag: MOVE_FLAGS.NORMAL },
],
},
],
};
const expectedMovesB: ExpectedMoves = {
black_queen: [
{
square: "a2",
moves: [
@@ -407,17 +473,7 @@ describe("queen and king moves", () => {
],
},
],
king: [
{
square: "g3",
moves: [
{ from: "g3", to: "f3", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "f4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "g4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "h4", flag: MOVE_FLAGS.NORMAL },
{ from: "g3", to: "h3", flag: MOVE_FLAGS.NORMAL },
],
},
black_king: [
{
square: "c7",
moves: [
@@ -431,5 +487,5 @@ describe("queen and king moves", () => {
],
};
runTest("7Q/2k5/8/8/8/6K1/q7/8 w - - 0 1", expectedMoves);
runTests("7Q/2k5/8/8/8/6K1/q7/8 % - - 0 1", expectedMovesW, expectedMovesB);
});
+1 -1
View File
@@ -8,5 +8,5 @@ test("", () => {
expect(chess.isSquareAttacked("e4", "b")).toBe(false);
expect(chess.isSquareAttacked("e5", "w")).toBe(false);
expect(chess.isSquareAttacked("e5", "b")).toBe(false);
expect(chess.isSquareAttacked("e5", "b")).toBe(true);
});
+30 -18
View File
@@ -512,23 +512,25 @@ export default class Chess {
this._halfMoves = halfMoves;
this._fullMoves = fullMoves;
this._computeMoves();
this._computeAttacks();
}
private _computeMoves() {
for (let i = 0; i < this._board.length; i++)
this._moves = this._moves.concat(this.getMovesForSquare(i));
}
private _computeAttacks() {
this._attacks = new Array(64).fill(0);
this.getMoves().forEach(({ from, to }) => {
const pieceColor = (this.getPiece(from) as Piece).color;
const square = squareIndex(to);
for (let i = 0; i < this._board.length; i++) {
const { piece, moves } = this._getMovesForSquare(i);
this._attacks[square] |= COLOR_MASKS[pieceColor];
});
this._moves = this._moves.concat(this._processMoves(piece, moves));
if (piece != null) {
const pieceColor = piece.color;
moves.forEach(
({ to }) =>
(this._attacks[squareIndex(to)] |= COLOR_MASKS[pieceColor])
);
}
}
}
static load(fen = DEFAULT_POSITION) {
@@ -667,16 +669,16 @@ export default class Chess {
return this._moves;
}
getMovesForSquare(square: Square | number): Move[] {
if (typeof square != "number") square = squareIndex(square);
private _getMovesForSquare(square: number) {
const piece = this.getPiece(square);
const moves =
piece == null ? [] : generatePieceMoves(this._board, square, piece);
if (piece == null || piece.color != this._turn) return [];
return { piece, moves };
}
const moves = generatePieceMoves(this._board, square, piece);
if (piece.type != PIECE.KING) return moves;
private _processMoves(piece: Piece | null, moves: Move[]) {
if (piece?.type != PIECE.KING) return moves;
const other_color = COLOR_MASKS[swapColor(piece.color)];
@@ -687,6 +689,16 @@ export default class Chess {
}, this);
}
getMovesForSquare(square: Square | number): Move[] {
if (typeof square != "number") square = squareIndex(square);
if (square < 0 || square > 63) return [];
const { piece, moves } = this._getMovesForSquare(square);
return this._processMoves(piece, moves);
}
makeMove() {}
isSquareAttacked(square: Square | number, color: Color) {