Just programming my first serious attempt at a chess engine, and I'm having a bit of trouble with null move pruning.
I've got my evaluation function set up so it's always relative to the player we started the search with, instead of alternating (negamax?) which is what I see in most of other people's code I've found (i.e. if at depth 0 it's black to play, +5 will mean a black advantage at any depth).
So from mediocre chess I found it implemented something like this:
Code: Select all
if(allowNull && !usingPreviousLine)
{
if(!isInCheck(board))
{
board.toMove *= -1; // Making a null-move
eval = -alphaBeta(board, ply-1-R, -beta,
-beta+1, localpv, false);
board.toMove *= -1; // Unmaking the null-move
if(eval >= beta) return eval; // Cutoff
}
}
So my code currently looks like this:
Code: Select all
if(allowNull){
Move _nullMove = Move.nullMove(pos); // this inverts the player to move
List bounds = isMaxNode?[beta, beta+0.01]:[alpha-0.01, alpha];
List _nabm = abm(_nullMove.endPosition, player, !isMaxNode, depth - 3, stage + 1, bounds[0], bounds[1], false, false); // abm is alpha-beta-with-memory, one of those falses sets allowNull for the next node
double eval = _nabm[0];
if((eval >= beta && isMaxNode) || eval <= alpha && !isMaxNode){
//print("null cutoff at ${isMaxNode?'max node':'min node'} ${pos.previousMove.name} depth: $stage, beta: $beta, eval: $eval");
pos.eval = eval;
return [eval];
}
}
Thanks!
edit: this code is near the start of abm, after transposition table lookup but before normal search.
edit 2: also if anyone has any suggestions of open source chess engines that use the same evaluation pattern as me I would appreciate links!