From 0a59d3e4d2d5c22ed0a446b1c970966ec708bb1e Mon Sep 17 00:00:00 2001 From: "Phu Minh (Catto)" <53084840+nguyenphuminh@users.noreply.github.com> Date: Sun, 28 Jul 2024 11:52:44 +0700 Subject: [PATCH] Add razoring (#19) --- README.md | 3 ++- catto.config.js | 2 +- package.json | 2 +- src/core.ts | 20 +++++++++++++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2aaf9fd..e0c6d7e 100644 --- a/README.md +++ b/README.md @@ -87,9 +87,10 @@ Note that the config file is compiled with the engine itself, so if you are usin * Countermove heuristic. * Transposition table. * Pruning: + * Reverse futility pruning. * Null-move pruning. + * Razoring. * Futility pruning. - * Reverse futility pruning. * Delta pruning. * Late move reductions. * Search extensions: diff --git a/catto.config.js b/catto.config.js index b19b948..3b04a82 100644 --- a/catto.config.js +++ b/catto.config.js @@ -1,6 +1,6 @@ module.exports = { // Current version to show in UCI - version: "v0.11.0", + version: "v0.12.0", // Late move reduction config lmrFullDepth: 4, // Number of moves to be searched in full depth lmrMaxReduction: 3, // Only apply LMR above this depth diff --git a/package.json b/package.json index c949d77..fd69265 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "catto", - "version": "0.11.0", + "version": "0.12.0", "description": "The Catto chess engine", "main": "index.js", "scripts": { diff --git a/src/core.ts b/src/core.ts index e4b7a43..0045c5f 100644 --- a/src/core.ts +++ b/src/core.ts @@ -303,8 +303,9 @@ export class Engine { if (depth === 0) return this.quiescence(alpha, beta); // Reverse futility pruning + const isPv = beta - alpha > 1; const currentEval = evaluateBoard(this.chess); - if (depth < 3 && !inCheck && !(beta - alpha > 1) && Math.abs(beta - 1) > -48900) { + if (depth < 3 && !inCheck && !isPv && Math.abs(beta - 1) > -48900) { let rfpMargin = mgMaterial[0] * depth; // Scaled for each depth by a pawn if (currentEval - rfpMargin >= beta) return currentEval - rfpMargin; @@ -363,6 +364,23 @@ export class Engine { possibleMoves = this.sortMoves(possibleMoves); let searchedMoves = 0, bestMoveSoFar: Move; + // Razoring, skipping an entire subtree + if (!isPv && !inCheck && depth <= 3) { + // Prepare score for first phase + let scaledScore = currentEval + mgMaterial[0]; + + if (scaledScore < beta) { + const qScore = this.quiescence(alpha, beta); + + if (depth === 1) return Math.max(qScore, scaledScore); + + // Second phase for depth 2 and depth 3 + scaledScore += mgMaterial[0]; + + if (scaledScore < beta && qScore < beta) return Math.max(qScore, scaledScore); + } + } + // Futility pruning let fpEnabled = false; if (depth < 4 && Math.abs(alpha) < 48000) {