test: add tests for knight moves

This commit is contained in:
Cozma Rares
2023-04-17 13:36:55 +03:00
parent 1bab968d15
commit da29d2623a
2 changed files with 247 additions and 40 deletions
+232 -21
View File
@@ -1,17 +1,37 @@
import { describe, expect, test } from "vitest";
import Chess, { MOVE_FLAGS, Move, Square } from "../chess/engine";
type ExpectedMove = {
square: Square;
moves: Move[];
};
type ExpectedMoves = Record<
string,
{
square: Square;
moves: Move[];
}[]
>;
describe("simple moves", () => {
function runTest(fen: string, expectedMoves: ExpectedMoves) {
const chess = Chess.load(fen);
Object.keys(expectedMoves).forEach(key =>
test(key.split("_").join(" "), () =>
expectedMoves[key].forEach(({ square, moves: expectedMoves }) => {
const moves = chess.getMovesForSquare(square);
expect(moves).toHaveLength(expectedMoves.length);
moves.forEach(move => expect(expectedMoves).toContainEqual(move));
expectedMoves.forEach(expectedMove =>
expect(moves).toContainEqual(expectedMove)
);
})
)
);
}
describe("piece moves", () => {
describe("pawn moves", () => {
const chess = Chess.load("7k/1P5p/5p2/4p3/3P4/2P5/P5p1/K7 w - - 0 1");
const expectedMoves: Record<string, ExpectedMove[]> = {
starting: [
const expectedMoves: ExpectedMoves = {
can_jump: [
{
square: "a2",
moves: [
@@ -159,19 +179,210 @@ describe("simple moves", () => {
],
};
Object.keys(expectedMoves).forEach(key =>
test(key, () =>
expectedMoves[key].forEach(({ square, moves: expectedMoves }) => {
const moves = chess.getMovesForSquare(square);
runTest("7k/1P5p/5p2/4p3/3P4/2P5/P5p1/K7 w - - 0 1", expectedMoves);
});
expect(moves).toHaveLength(expectedMoves.length);
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,
},
],
},
],
exclude_g: [
{
square: "g2",
moves: [
{
from: "g2",
to: "e1",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "g2",
to: "e3",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "g2",
to: "f4",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "g2",
to: "h4",
flag: MOVE_FLAGS.NORMAL,
},
],
},
],
exclude_h: [
{
square: "h1",
moves: [
{
from: "h1",
to: "f2",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "h1",
to: "g3",
flag: MOVE_FLAGS.NORMAL,
},
],
},
],
attack: [
{
square: "a2",
moves: [
{
from: "a2",
to: "c1",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "a2",
to: "c3",
flag: MOVE_FLAGS.CAPTURE,
},
{
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: [
{
square: "e5",
moves: [
{
from: "e5",
to: "g6",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "f7",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "d7",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "c6",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "c4",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "d3",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "f3",
flag: MOVE_FLAGS.NORMAL,
},
{
from: "e5",
to: "g4",
flag: MOVE_FLAGS.NORMAL,
},
],
},
],
};
moves.forEach(move => expect(expectedMoves).toContainEqual(move));
expectedMoves.forEach(expectedMove =>
expect(moves).toContainEqual(expectedMove)
);
})
)
);
runTest("n7/1n6/8/1K1kN3/8/2n5/N5N1/7N w - - 0 1", expectedMoves);
});
});
+15 -19
View File
@@ -271,14 +271,14 @@ const PIECE_MOVE_INFO = Object.freeze({
n: {
generateMultiple: false,
moves: [
{ offset: -17, excludedFiles: [FILE.A] },
{ offset: -10, excludedFiles: [FILE.A, FILE.B] },
{ offset: -17, excludedFiles: [FILE.H] },
{ offset: -15, excludedFiles: [FILE.A] },
{ offset: -6, excludedFiles: [FILE.G, FILE.H] },
{ offset: 10, excludedFiles: [FILE.G, FILE.H] },
{ offset: 17, excludedFiles: [FILE.G] },
{ offset: 15, excludedFiles: [FILE.A] },
{ offset: 6, excludedFiles: [FILE.A, FILE.B] },
{ offset: 15, excludedFiles: [FILE.A] },
{ offset: 17, excludedFiles: [FILE.H] },
{ offset: 10, excludedFiles: [FILE.G, FILE.H] },
{ offset: -6, excludedFiles: [FILE.G, FILE.H] },
{ offset: -15, excludedFiles: [FILE.H] },
],
},
b: {
@@ -406,30 +406,26 @@ export function generatePieceMoves(
const moves: Move[] = [];
PIECE_MOVE_INFO[type].moves.forEach(({ offset, excludedFiles }) => {
if (excludedFiles.includes(file(position))) return;
const nextPosition = position + offset;
if (nextPosition < 0 || nextPosition >= 64) return;
if (excludedFiles.includes(file(nextPosition))) return;
const attackedPiece = board[nextPosition];
if (attackedPiece == null) {
if (attackedPiece == null)
moves.push({
from: algebraic(position),
to: algebraic(nextPosition),
flag: MOVE_FLAGS.NORMAL,
});
return;
}
if (attackedPiece.color == piece.color) return;
moves.push({
from: algebraic(position),
to: algebraic(nextPosition),
flag: MOVE_FLAGS.CAPTURE,
});
else if (attackedPiece.color != piece.color)
moves.push({
from: algebraic(position),
to: algebraic(nextPosition),
flag: MOVE_FLAGS.CAPTURE,
});
});
return moves;