P.S.
Code: Select all
//make and unmake null moves respectively
inline void Legal_Moves::push_null_move(){
//Skip turn
side_to_move ^= 1;
//Nullify the en passant square
En_Passant_Sq.push_back(64);
}
inline void Legal_Moves::pop_null_move(){
//Revert turn
side_to_move ^= 1;
//Set en passant vector back to original state before null move
En_Passant_Sq.pop_back();
}
//Principal Variation Search with LMR
inline int pvs(int alpha, int beta, int depth, int ply, bool can_null, HISTORY &history, KILLER &killer, Legal_Moves &board){
...
//Null Move Pruning
if(depth >= 3 && !check && can_null && ply){
//Make Null Move
board.push_null_move();
score = -pvs(-beta, -beta + 1, depth - 3, ply + 1, false, history, killer, board);
can_null = false;
//Unmake null move
board.pop_null_move();
// fail-hard beta cutoff
if(score >= beta){
// node fails high
return beta;
}
...
for(int i = 0; i < move_list.size(); i++){
get_best_move(move_list, i);
move = move_list[i];
board.push_move(move);
nodes++;
bool gives_check = board.in_check();
if(moves_searched == 0){
score = -pvs(-beta, -alpha, depth - 1, ply + 1, can_null, history, killer, board);
} else {
if(moves_searched >= full_depth_moves && depth >= reduction_limit && move.capture == E && !move.promoted && !check && !gives_check){
score = -pvs(-alpha - 1, -alpha, depth - 2, ply + 1, can_null, history, killer, board);
} else {
score = alpha + 1;
}
if(score > alpha) {
score = -pvs(-alpha - 1, -alpha, depth - 1, ply + 1, can_null, history, killer, board);
if(score > alpha && score < beta){
score = -pvs(-beta, -alpha, depth - 1, ply + 1, can_null, history, killer, board);
}
}
}
board.pop_move(move);
moves_searched++;
…
}