Skip to content

Commit

Permalink
Resolve rare en passant bug (#21)
Browse files Browse the repository at this point in the history
* Added en passant step to move validation to prevent en passant moves
that leave the king in check.
* For an example of such a position see:
`1nbqkbnr/1pp1pppp/8/r1Pp3K/p7/5P2/PP1PP1PP/RNBQ1BNR w k d6 0 8`

fixes #18
  • Loading branch information
pdil authored Apr 30, 2024
2 parents eb9cf84 + a07af0d commit ed182a5
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
9 changes: 6 additions & 3 deletions Sources/ChessKit/Board.swift
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,19 @@ 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)

var movedPiece = piece
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)
}

Expand Down
6 changes: 6 additions & 0 deletions Tests/ChessKitTests/BoardTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit ed182a5

Please sign in to comment.