From 9331729d765fc9347f769c310f1fff4bc39fdbad Mon Sep 17 00:00:00 2001 From: Mattia Giambirtone Date: Sat, 11 May 2024 11:25:45 +0200 Subject: [PATCH] Add SEE to move ordering (gains 44.7 +/- 22.9) --- Chess/nimfish/nimfishpkg/search.nim | 51 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/Chess/nimfish/nimfishpkg/search.nim b/Chess/nimfish/nimfishpkg/search.nim index eefebfe..13762f6 100644 --- a/Chess/nimfish/nimfishpkg/search.nim +++ b/Chess/nimfish/nimfishpkg/search.nim @@ -81,12 +81,11 @@ const # higher offsets will always be placed # first TTMOVE_OFFSET = 700_000 - MVV_LVA_OFFSET = 600_000 - GOOD_SEE_OFFSET {.used.} = 500_000 - KILLERS_OFFSET = 400_000 - HISTORY_OFFSET = 300_000 - QUIET_OFFSET = 200_000 - BAD_SEE_OFFSET {.used.} = 100_000 + GOOD_SEE_OFFSET = 600_000 + KILLERS_OFFSET = 500_000 + HISTORY_OFFSET = 400_000 + QUIET_OFFSET = 300_000 + BAD_SEE_OFFSET = 200_000 func computeLMRTable: array[MAX_DEPTH, array[218, int]] {.compileTime.} = @@ -187,7 +186,10 @@ proc getEstimatedMoveScore(self: SearchManager, move: Move, ply: int): int = return KILLERS_OFFSET if move.isTactical(): - if move.isCapture(): + let seeScore = self.board.position.see(move) + # We want to prioritize good captures (see > 0), but if the capture + # is bad then at least we sort it with MVVLVA + if seeScore < 0 and (move.isCapture() or move.isEnPassant()): # Implementation of MVVLVA: Most Valuable Victim Least Valuable Aggressor. # We prioritize moves that capture the most valuable pieces, and as a # second goal we want to use our least valuable pieces to do so (this @@ -196,23 +198,26 @@ proc getEstimatedMoveScore(self: SearchManager, move: Move, ply: int): int = let capturedScore = MVV_LVA_MULTIPLIER * self.board.position.getPieceScore(move.targetSquare) result = capturedScore - self.board.position.getPieceScore(move.startSquare) - # If the capture is also a promotion we want to give it an even bigger bonus - if move.isPromotion(): - var piece: Piece - case move.getPromotionType(): - of PromoteToBishop: - piece = Piece(kind: Bishop, color: sideToMove) - of PromoteToKnight: - piece = Piece(kind: Knight, color: sideToMove) - of PromoteToRook: - piece = Piece(kind: Rook, color: sideToMove) - of PromoteToQueen: - piece = Piece(kind: Queen, color: sideToMove) - else: - discard # Unreachable - result += PROMOTION_MULTIPLIER * self.board.position.getPieceScore(piece, move.targetSquare) + # If the capture is also a promotion we want to give it an even bigger bonus + if move.isPromotion(): + var piece: Piece + case move.getPromotionType(): + of PromoteToBishop: + piece = Piece(kind: Bishop, color: sideToMove) + of PromoteToKnight: + piece = Piece(kind: Knight, color: sideToMove) + of PromoteToRook: + piece = Piece(kind: Rook, color: sideToMove) + of PromoteToQueen: + piece = Piece(kind: Queen, color: sideToMove) + else: + discard # Unreachable + result += PROMOTION_MULTIPLIER * self.board.position.getPieceScore(piece, move.targetSquare) - return result + MVV_LVA_OFFSET + return result + BAD_SEE_OFFSET + else: + # If the capture is good then we just use the SEE score + the offset + return seeScore + GOOD_SEE_OFFSET if move.isQuiet(): # History heuristic bonus