X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=0c5ead46754c20411fe6ab3de99953dceb884524;hp=804108b42b3815487692eac98bfa866c69ad9a6d;hb=e9de96f0e417dc706882b645d14dbf41e7ccc467;hpb=a5d699d62fb625fba23b23bdeff2a68807ef6438 diff --git a/src/search.cpp b/src/search.cpp index 804108b4..0c5ead46 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1281,21 +1281,57 @@ namespace { bool mateThreat = false; bool isCheck = pos.is_check(); - bool useNullMove = ( allowNullmove - && depth > OnePly - && !isCheck - && !value_is_mate(beta) - && ok_to_do_nullmove(pos) - && approximateEval >= beta - NullMoveMargin); + // Null move search + if ( allowNullmove + && depth > OnePly + && !isCheck + && !value_is_mate(beta) + && ok_to_do_nullmove(pos) + && approximateEval >= beta - NullMoveMargin) + { + ss[ply].currentMove = MOVE_NULL; + + StateInfo st; + pos.do_null_move(st); + int R = (depth >= 5 * OnePly ? 4 : 3); // Null move dynamic reduction + + Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID); + + pos.undo_null_move(); + if (nullValue >= beta) + { + if (depth < 6 * OnePly) + return beta; + + // Do zugzwang verification search + Value v = search(pos, ss, beta, depth-5*OnePly, ply, false, threadID); + if (v >= beta) + return beta; + } else { + // The null move failed low, which means that we may be faced with + // some kind of threat. If the previous move was reduced, check if + // the move that refuted the null move was somehow connected to the + // move which was reduced. If a connection is found, return a fail + // low score (which will cause the reduced move to fail high in the + // parent node, which will trigger a re-search with full depth). + if (nullValue == value_mated_in(ply + 2)) + mateThreat = true; + + ss[ply].threatMove = ss[ply + 1].currentMove; + if ( depth < ThreatDepth + && ss[ply - 1].reduction + && connected_moves(pos, ss[ply - 1].currentMove, ss[ply].threatMove)) + return beta - 1; + } + } // Null move search not allowed, try razoring - if ( !useNullMove - && !value_is_mate(beta) - && depth < RazorDepth - && approximateEval < beta - RazorApprMargins[int(depth) - 2] - && ss[ply - 1].currentMove != MOVE_NULL - && ttMove == MOVE_NONE - && !pos.has_pawn_on_7th(pos.side_to_move())) + else if ( !value_is_mate(beta) + && depth < RazorDepth + && approximateEval < beta - RazorApprMargins[int(depth) - 2] + && ss[ply - 1].currentMove != MOVE_NULL + && ttMove == MOVE_NONE + && !pos.has_pawn_on_7th(pos.side_to_move())) { Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID); if (v < beta - RazorMargins[int(depth) - 2]) @@ -1312,7 +1348,7 @@ namespace { // Initialize a MovePicker object for the current position, and prepare // to search all moves. - MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply], useNullMove); + MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]); Move move, movesSearched[256]; int moveCount = 0; @@ -1328,48 +1364,6 @@ namespace { && (move = mp.get_next_move()) != MOVE_NONE && !thread_should_stop(threadID)) { - - // Null move search - if (move == MOVE_NULL) - { - ss[ply].currentMove = MOVE_NULL; - - StateInfo st; - pos.do_null_move(st); - int R = (depth >= 5 * OnePly ? 4 : 3); // Null move dynamic reduction - - Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID); - - pos.undo_null_move(); - - if (nullValue >= beta) - { - if (depth < 6 * OnePly) - return beta; - - // Do zugzwang verification search - Value v = search(pos, ss, beta, depth-5*OnePly, ply, false, threadID); - if (v >= beta) - return beta; - } else { - // The null move failed low, which means that we may be faced with - // some kind of threat. If the previous move was reduced, check if - // the move that refuted the null move was somehow connected to the - // move which was reduced. If a connection is found, return a fail - // low score (which will cause the reduced move to fail high in the - // parent node, which will trigger a re-search with full depth). - if (nullValue == value_mated_in(ply + 2)) - mateThreat = true; - - ss[ply].threatMove = ss[ply + 1].currentMove; - if ( depth < ThreatDepth - && ss[ply - 1].reduction - && connected_moves(pos, ss[ply - 1].currentMove, ss[ply].threatMove)) - return beta - 1; - } - continue; - } - assert(move_is_ok(move)); bool singleReply = (isCheck && mp.number_of_moves() == 1); @@ -1968,15 +1962,15 @@ namespace { bool includeAllMoves = (searchMoves[0] == MOVE_NONE); // Generate all legal moves - int lm_count = generate_legal_moves(pos, mlist); + MoveStack* last = generate_legal_moves(pos, mlist); // Add each move to the moves[] array - for (int i = 0; i < lm_count; i++) + for (MoveStack* cur = mlist; cur != last; cur++) { bool includeMove = includeAllMoves; for (int k = 0; !includeMove && searchMoves[k] != MOVE_NONE; k++) - includeMove = (searchMoves[k] == mlist[i].move); + includeMove = (searchMoves[k] == cur->move); if (!includeMove) continue; @@ -1985,7 +1979,7 @@ namespace { StateInfo st; SearchStack ss[PLY_MAX_PLUS_2]; - moves[count].move = mlist[i].move; + moves[count].move = cur->move; pos.do_move(moves[count].move, st); moves[count].score = -qsearch(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1, 0); pos.undo_move(moves[count].move);