Minor (hopefully last) movegen bugfix

This commit is contained in:
Mattia Giambirtone 2024-04-23 20:42:57 +02:00
parent 584a29618a
commit 52100835a9
2 changed files with 17 additions and 9 deletions

View File

@ -17,4 +17,6 @@ requires "jsony >= 1.1.5"
task test, "Runs the test suite":
exec "python tests/suite.py -d 6 --bulk"
exec "python tests/suite.py -d 6 -b -p -s"
# TODO: Also run fewer, more intense test
# for more precise results

View File

@ -127,9 +127,11 @@ proc generatePawnMoves(self: Chessboard, moves: var MoveList, destinationMask: B
if epBitboard != 0:
# See if en passant would create a check
let
# We don't and the destination mask with the ep target because we already check
# whether the king ends up in check. TODO: Fix this in a more idiomatic way
epPawn = epBitboard.backwardRelativeTo(sideToMove)
epLeft = pawns.forwardLeftRelativeTo(sideToMove) and epBitboard and destinationMask
epRight = pawns.forwardRightRelativeTo(sideToMove) and epBitboard and destinationMask
epLeft = pawns.forwardLeftRelativeTo(sideToMove) and epBitboard
epRight = pawns.forwardRightRelativeTo(sideToMove) and epBitboard
# Note: it's possible for two pawns to both have rights to do an en passant! See
# 4k3/8/8/2PpP3/8/8/8/4K3 w - d6 0 1
if epLeft != 0:
@ -175,6 +177,7 @@ proc generateRookMoves(self: Chessboard, moves: var MoveList, destinationMask: B
pinMask = self.position.orthogonalPins
pinnedRooks = movableRooks and pinMask
unpinnedRooks = movableRooks and not pinnedRooks
for square in pinnedRooks:
let
blockers = occupancy and Rook.getRelevantBlockers(square)
@ -183,6 +186,7 @@ proc generateRookMoves(self: Chessboard, moves: var MoveList, destinationMask: B
moves.add(createMove(square, target))
for target in moveset and enemyPieces and pinMask and destinationMask:
moves.add(createMove(square, target, Capture))
for square in unpinnedRooks:
let
blockers = occupancy and Rook.getRelevantBlockers(square)
@ -307,12 +311,14 @@ proc generateMoves*(self: Chessboard, moves: var MoveList) =
epTarget = self.position.enPassantSquare
checkerPiece = self.getPiece(checker)
destinationMask = getRayBetween(checker, self.getBitboard(King, sideToMove).toSquare()) or checkerBB
if checkerPiece.kind == Pawn and checkerBB.backwardRelativeTo(checkerPiece.color).toSquare() == epTarget:
# We are in check by a pawn that pushed two squares: add the ep target square to the set of
# squares that our friendly pieces can move to in order to resolve it. This will do nothing
# for most pieces, because the move generators won't allow them to move there, but it does matter
# for pawns
destinationMask = destinationMask or epTarget.toBitboard()
# TODO: This doesn't really work. I've addressed the issue for now, but it's kinda ugly. Find a better
# solution
# if checkerPiece.kind == Pawn and checkerBB.backwardRelativeTo(checkerPiece.color).toSquare() == epTarget:
# # We are in check by a pawn that pushed two squares: add the ep target square to the set of
# # squares that our friendly pieces can move to in order to resolve it. This will do nothing
# # for most pieces, because the move generators won't allow them to move there, but it does matter
# # for pawns
# destinationMask = destinationMask or epTarget.toBitboard()
self.generatePawnMoves(moves, destinationMask)
self.generateKnightMoves(moves, destinationMask)
self.generateRookMoves(moves, destinationMask)