test: add tests for knight moves
This commit is contained in:
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user