From a07af0d94e7733514b5948d0725582a9e9618d73 Mon Sep 17 00:00:00 2001 From: Paolo Di Lorenzo Date: Mon, 29 Apr 2024 22:33:48 -0400 Subject: [PATCH] Add en passant to move validation check --- CHANGELOG.md | 4 ++++ Sources/ChessKit/Board.swift | 9 ++++++--- Tests/ChessKitTests/BoardTests.swift | 6 ++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecfd2fc..5bc1d26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # [unreleased] +#### Improvements * Add `startingIndex` and `startingPosition` to `Game`. * `startingIndex` takes into account the `sideToMove` of `startingPosition`. +#### Bug Fixes +* Fix rare en passant issue that could allow the king to be left in check, see [Issue #18](https://github.com/chesskit-app/chesskit-swift/issues/18). + # ChessKit 0.6.0 Released Friday, April 19, 2024. diff --git a/Sources/ChessKit/Board.swift b/Sources/ChessKit/Board.swift index a3a2740..ccdadeb 100644 --- a/Sources/ChessKit/Board.swift +++ b/Sources/ChessKit/Board.swift @@ -321,9 +321,6 @@ public struct Board { /// private func validate(moveFor piece: Piece, to square: Square) -> Bool { // attempt move in test set - // - // to-do: prune pseudo legal moves for sliding pieces - // based on diagonals, lines, etc if pinned var testSet = set testSet.remove(piece) @@ -331,6 +328,12 @@ public struct Board { movedPiece.square = square testSet.add(movedPiece) + if let enPassant = position.enPassant { + if enPassant.canBeCaptured(by: piece) && enPassant.captureSquare == square { + testSet.remove(enPassant.pawn) + } + } + return !isKingInCheck(piece.color, set: testSet) } diff --git a/Tests/ChessKitTests/BoardTests.swift b/Tests/ChessKitTests/BoardTests.swift index 200ed22..bc6ee2d 100644 --- a/Tests/ChessKitTests/BoardTests.swift +++ b/Tests/ChessKitTests/BoardTests.swift @@ -45,6 +45,12 @@ class BoardTests: XCTestCase { XCTAssertEqual(move.result, .capture(ep.pawn)) } + func testIllegalEnPassant() { + // fen position contains illegal en passant move + let board = Board(position: .init(fen: "1nbqkbnr/1pp1pppp/8/r1Pp3K/p7/5P2/PP1PP1PP/RNBQ1BNR w k d6 0 8")!) + XCTAssertFalse(board.canMove(pieceAt: .c5, to: .d6)) + } + func testCastling() { var board = Board(position: .castling) XCTAssertTrue(board.position.legalCastlings.contains(.bK))