From e9de96f0e417dc706882b645d14dbf41e7ccc467 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sat, 29 Aug 2009 20:19:09 +0100 Subject: [PATCH] Revert "null move reorder" series Does not seem to improve on the standard, latest results from Joona after 2040 games are negative: Orig - Mod: 454 - 424 - 1162 And is more or less the same I got few days ago. So revert for now. Verified same functionality of 595a90dfd Signed-off-by: Marco Costalba --- src/movepick.cpp | 17 ++------ src/movepick.h | 3 +- src/search.cpp | 106 ++++++++++++++++++++++------------------------- 3 files changed, 54 insertions(+), 72 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index a9cc245d..6b7483eb 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -40,9 +40,7 @@ namespace { CACHE_LINE_ALIGNMENT - const MovegenPhaseT MainSearchPhaseTable[] = { PH_NULL_MOVE, PH_TT_MOVES, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP}; - const MovegenPhaseT MainSearchNoNullPhaseTable[] = { PH_TT_MOVES, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP}; - const MovegenPhaseT LowSearchPhaseTable[] = { PH_TT_MOVES, PH_NULL_MOVE, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP}; + const MovegenPhaseT MainSearchPhaseTable[] = { PH_TT_MOVES, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP}; const MovegenPhaseT EvasionsPhaseTable[] = { PH_EVASIONS, PH_STOP}; const MovegenPhaseT QsearchWithChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_QCHECKS, PH_STOP}; const MovegenPhaseT QsearchWithoutChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_STOP}; @@ -62,7 +60,7 @@ namespace { /// move ordering is at the current node. MovePicker::MovePicker(const Position& p, Move ttm, Depth d, - const History& h, SearchStack* ss, bool useNullMove) : pos(p), H(h) { + const History& h, SearchStack* ss) : pos(p), H(h) { ttMoves[0].move = ttm; if (ss) { @@ -82,10 +80,8 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, if (p.is_check()) phasePtr = EvasionsPhaseTable; - else if (d >= Depth(3 * OnePly)) - phasePtr = useNullMove ? MainSearchPhaseTable : MainSearchNoNullPhaseTable; else if (d > Depth(0)) - phasePtr = useNullMove ? LowSearchPhaseTable : MainSearchNoNullPhaseTable; + phasePtr = MainSearchPhaseTable; else if (d == Depth(0)) phasePtr = QsearchWithChecksPhaseTable; else @@ -105,9 +101,6 @@ void MovePicker::go_next_phase() { phase = *(++phasePtr); switch (phase) { - case PH_NULL_MOVE: - return; - case PH_TT_MOVES: curMove = ttMoves; lastMove = curMove + 2; @@ -258,10 +251,6 @@ Move MovePicker::get_next_move() { { switch (phase) { - case PH_NULL_MOVE: - go_next_phase(); - return MOVE_NULL; - case PH_TT_MOVES: while (curMove != lastMove) { diff --git a/src/movepick.h b/src/movepick.h index b31d9dd2..147d5d0b 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -38,7 +38,6 @@ struct SearchStack; enum MovegenPhase { - PH_NULL_MOVE, // Null move PH_TT_MOVES, // Transposition table move and mate killer PH_GOOD_CAPTURES, // Queen promotions and captures with SEE values >= 0 PH_KILLERS, // Killer moves from the current ply @@ -65,7 +64,7 @@ class MovePicker { MovePicker& operator=(const MovePicker&); // silence a warning under MSVC public: - MovePicker(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss = NULL, bool useNullMove = false); + MovePicker(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss = NULL); Move get_next_move(); Move get_next_move(Lock& lock); int number_of_moves() const; diff --git a/src/search.cpp b/src/search.cpp index d93493c2..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); -- 2.39.2