From 21b6de8d21593bed7b6c85319e8c7412064e1eb8 Mon Sep 17 00:00:00 2001 From: Cozma Rares Date: Mon, 17 Apr 2023 14:07:32 +0300 Subject: [PATCH] test: add tests for bishop moves --- server/src/__test__/getMovesForSquare.test.ts | 1037 +++++++++++------ server/src/chess/engine.ts | 16 +- 2 files changed, 690 insertions(+), 363 deletions(-) diff --git a/server/src/__test__/getMovesForSquare.test.ts b/server/src/__test__/getMovesForSquare.test.ts index cf8d919..c7cdf17 100644 --- a/server/src/__test__/getMovesForSquare.test.ts +++ b/server/src/__test__/getMovesForSquare.test.ts @@ -28,361 +28,686 @@ function runTest(fen: string, expectedMoves: ExpectedMoves) { ); } -describe("piece moves", () => { - describe("pawn moves", () => { - const expectedMoves: ExpectedMoves = { - can_jump: [ - { - square: "a2", - moves: [ - { - from: "a2", - to: "a3", - flag: MOVE_FLAGS.NORMAL, - }, - { - 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: [ - { - square: "b7", - moves: [ - { - from: "b7", - to: "b8", - flag: MOVE_FLAGS.PROMOTION, - promotion: "n", - }, - { - from: "b7", - to: "b8", - flag: MOVE_FLAGS.PROMOTION, - promotion: "b", - }, - { - from: "b7", - to: "b8", - flag: MOVE_FLAGS.PROMOTION, - promotion: "r", - }, - { - from: "b7", - to: "b8", - flag: MOVE_FLAGS.PROMOTION, - promotion: "q", - }, - ], - }, - { - square: "g2", - moves: [ - { - from: "g2", - to: "g1", - flag: MOVE_FLAGS.PROMOTION, - promotion: "n", - }, - { - from: "g2", - to: "g1", - flag: MOVE_FLAGS.PROMOTION, - promotion: "b", - }, - { - from: "g2", - to: "g1", - flag: MOVE_FLAGS.PROMOTION, - promotion: "r", - }, - { - from: "g2", - to: "g1", - flag: MOVE_FLAGS.PROMOTION, - promotion: "q", - }, - ], - }, - ], - 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: [ - { - from: "e5", - to: "e4", - flag: MOVE_FLAGS.NORMAL, - }, - { - from: "e5", - to: "d4", - flag: MOVE_FLAGS.CAPTURE, - }, - ], - }, - ], - }; +describe("pawn moves", () => { + const expectedMoves: ExpectedMoves = { + can_jump: [ + { + square: "a2", + moves: [ + { + from: "a2", + to: "a3", + flag: MOVE_FLAGS.NORMAL, + }, + { + 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: [ + { + square: "b7", + moves: [ + { + from: "b7", + to: "b8", + flag: MOVE_FLAGS.PROMOTION, + promotion: "n", + }, + { + from: "b7", + to: "b8", + flag: MOVE_FLAGS.PROMOTION, + promotion: "b", + }, + { + from: "b7", + to: "b8", + flag: MOVE_FLAGS.PROMOTION, + promotion: "r", + }, + { + from: "b7", + to: "b8", + flag: MOVE_FLAGS.PROMOTION, + promotion: "q", + }, + ], + }, + { + square: "g2", + moves: [ + { + from: "g2", + to: "g1", + flag: MOVE_FLAGS.PROMOTION, + promotion: "n", + }, + { + from: "g2", + to: "g1", + flag: MOVE_FLAGS.PROMOTION, + promotion: "b", + }, + { + from: "g2", + to: "g1", + flag: MOVE_FLAGS.PROMOTION, + promotion: "r", + }, + { + from: "g2", + to: "g1", + flag: MOVE_FLAGS.PROMOTION, + promotion: "q", + }, + ], + }, + ], + 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: [ + { + from: "e5", + to: "e4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "e5", + to: "d4", + flag: MOVE_FLAGS.CAPTURE, + }, + ], + }, + ], + }; - runTest("7k/1P5p/5p2/4p3/3P4/2P5/P5p1/K7 w - - 0 1", expectedMoves); - }); - - 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, - }, - ], - }, - ], - }; - - runTest("n7/1n6/8/1K1kN3/8/2n5/N5N1/7N w - - 0 1", expectedMoves); - }); + runTest("7k/1P5p/5p2/4p3/3P4/2P5/P5p1/K7 w - - 0 1", expectedMoves); +}); + +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, + }, + ], + }, + ], + }; + + runTest("n7/1n6/8/1K1kN3/8/2n5/N5N1/7N w - - 0 1", expectedMoves); +}); + +describe("bishop moves", () => { + const expectedMoves: ExpectedMoves = { + exclude_a: [ + { + square: "a2", + moves: [ + { + from: "a2", + to: "b3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "c4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "d5", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "e6", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "f7", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "g8", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "a2", + to: "b1", + flag: MOVE_FLAGS.NORMAL, + }, + ], + }, + ], + 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", + moves: [ + { + from: "d2", + to: "c1", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "e1", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "c3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "b4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "a5", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "e3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "f4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d2", + to: "g5", + flag: MOVE_FLAGS.CAPTURE, + }, + ], + }, + { + square: "g5", + moves: [ + { + from: "g5", + to: "h6", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "h4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "f6", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "e7", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "d8", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "f4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "e3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "g5", + to: "d2", + flag: MOVE_FLAGS.CAPTURE, + }, + ], + }, + ], + attack_same_color: [ + { + square: "c5", + moves: [ + { + from: "c5", + to: "b6", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "a7", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "d4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "e3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "f2", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "g1", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "b4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "c5", + to: "a3", + flag: MOVE_FLAGS.NORMAL, + }, + ], + }, + { + square: "d6", + moves: [ + { + from: "d6", + to: "c7", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "b8", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "e7", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "f8", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "e5", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "f4", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "g3", + flag: MOVE_FLAGS.NORMAL, + }, + { + from: "d6", + to: "h2", + flag: MOVE_FLAGS.NORMAL, + }, + ], + }, + ], + 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); }); diff --git a/server/src/chess/engine.ts b/server/src/chess/engine.ts index 36acf4a..0d6bf95 100644 --- a/server/src/chess/engine.ts +++ b/server/src/chess/engine.ts @@ -284,8 +284,8 @@ const PIECE_MOVE_INFO = Object.freeze({ b: { generateMultiple: true, moves: [ - { offset: -9, excludedFiles: [FILE.H] }, - { offset: -7, excludedFiles: [FILE.A] }, + { offset: -9, excludedFiles: [FILE.A] }, + { offset: -7, excludedFiles: [FILE.H] }, { offset: 9, excludedFiles: [FILE.H] }, { offset: 7, excludedFiles: [FILE.A] }, ], @@ -435,13 +435,11 @@ export function generatePieceMoves( const moves: Move[] = []; PIECE_MOVE_INFO[type].moves.forEach(({ offset, excludedFiles }) => { + if (excludedFiles.includes(file(position))) return; + let nextPosition = position + offset; - while ( - nextPosition >= 0 && - nextPosition < 64 && - !excludedFiles.includes(file(nextPosition)) - ) { + while (nextPosition >= 0 && nextPosition < 64) { const attackedPiece = board[nextPosition]; if (attackedPiece == null) { @@ -450,7 +448,11 @@ export function generatePieceMoves( to: algebraic(nextPosition), flag: MOVE_FLAGS.NORMAL, }); + + if (excludedFiles.includes(file(nextPosition))) break; + nextPosition += offset; + continue; }