From 6bfe8f5f7d934eef8330f86b2a9980db675fd2d6 Mon Sep 17 00:00:00 2001 From: Maurizio Monge Date: Tue, 9 Oct 2007 06:30:11 +0200 Subject: [PATCH] More search tunings and features (NULL SOLIDITY) --- search.cpp | 144 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 83 insertions(+), 61 deletions(-) diff --git a/search.cpp b/search.cpp index 67e9998..8332940 100644 --- a/search.cpp +++ b/search.cpp @@ -80,6 +80,9 @@ void print_stats() /* enable the null move */ #define NULL_MOVE 1 +/* il null move > beta-margin, reduce (not a dangerous position). Set to 1 to disable */ +#define NULL_SOLIDITY_MARGIN 100 + /* before doing the alpha beta search check if any of the following positions can give use an early cutoff thanks to the hashtable */ #define EARLY_TRANSP_CUTOFF 1 @@ -98,7 +101,7 @@ void print_stats() #define HISTORY_HEURISTIC 1 /* improve the sorting heuristic for pawn strikes */ -#define PAWN_STRIKE 0 +#define PAWN_STRIKE 1 /* improve the sorting heuristic for moves to the center */ #define CENTER_HEURISTIC 0 @@ -242,7 +245,7 @@ SearchRoot::moves_heuristic(Move *mv, int num_mv, bool pv, int ply, int orig_dep #if PAWN_STRIKE if(num_escapes<=2 && PIECE_OF(board.data[mv[i].from]) != PAWN && - (mv[i].from == escape_from_1[ply-1] || mv[i].from == escape_from_2[ply-1]) ) + (mv[i].from == stack[ply-1].escape_from[1] || stack[ply-1].escape_from[2]) ) { int x = board.move_see_val(mv[i]); @@ -365,7 +368,11 @@ SearchRoot::moves_heuristic(Move *mv, int num_mv, bool pv, int ply, int orig_dep } #if 1 + if(expect_allbad) + continue; + mv[i].val += (history_hit[HISTORY_INDEX(mv[i])] + 32) * 1024/3 / (history_tot[HISTORY_INDEX(mv[i])] + 64); + if(stack[ply-1].curr_move>=0) { int ix = PLUTO_INDEX(stack[ply-1].moves[stack[ply-1].curr_move], mv[i]); @@ -403,7 +410,7 @@ SearchRoot::moves_heuristic(Move *mv, int num_mv, bool pv, int ply, int orig_dep } #if PAWN_STRIKE - if(escape_from_1[ply-1] != INVALID || escape_from_2[ply-1] != INVALID) + if(stack[ply-1].escape_from[1] != INVALID || stack[ply-1].escape_from[2] != INVALID) { if(num_escapes <= 2) for(int i=0;inull_threat = Move::FromInt(0); s->null_threat_dangerous = false; #if PAWN_STRIKE - escape_from_1[ply] = escape_from_2[ply] = INVALID; + stack[ply].escape_from[1] = stack[ply].escape_from[2] = INVALID; #endif //PAWN_STRIKE /* check if time is running out */ @@ -645,7 +652,7 @@ int16_t SearchRoot::search(int ply, int base_depth, bool pv, int16_t orig_alpha, /******************************************************************************* Try the null move. *******************************************************************************/ - if(!expect_allbad && !s->under_check && (stack[ply-1].curr_move != -1) && depth >= 2*PLY && betaunder_check && (stack[ply-1].curr_move != -1) && depth >= 2*PLY && beta= 5*PLY) ? (depth-4*PLY) : depth-3*PLY; @@ -653,7 +660,7 @@ int16_t SearchRoot::search(int ply, int base_depth, bool pv, int16_t orig_alpha, s->curr_move = -1; board.do_null_move(s->save_buf); GUI1(notify(Move::None(), ply, sdepth, -INF, beta-1, beta, SearchGui::Green )); - val = -search( ply+1, sdepth, false, -beta, -beta+1, false); + val = -search( ply+1, sdepth, false, -beta, -beta+NULL_SOLIDITY_MARGIN, false); GUI2(notify_value(ply, val, DIFF_NODES, SearchGui::Bold )); board.undo_null_move(s->save_buf); @@ -661,6 +668,11 @@ int16_t SearchRoot::search(int ply, int base_depth, bool pv, int16_t orig_alpha, if(val >= beta) return val; +#if NULL_SOLIDITY_MARGIN > 1 + if(val > beta - NULL_SOLIDITY_MARGIN) + depth -= PLY; +#endif + if(val < -WORST_MATE) s->null_threat_dangerous = true; @@ -886,59 +898,62 @@ int16_t SearchRoot::search(int ply, int base_depth, bool pv, int16_t orig_alpha, } #endif - /* collect history statistics */ - if(!s->moves[i].capture && - !(s->moves[i].flags>=PROMOTE_FIRST) ) + if(!expect_allbad) { - int ix = HISTORY_INDEX(s->moves[i]); - if(history_tot[ix] > 1024) + /* collect history statistics */ + if(!s->moves[i].capture && + !(s->moves[i].flags>=PROMOTE_FIRST) ) { - history_tot[ix] = history_tot[ix]*7/8; - history_hit[ix] = history_hit[ix]*7/8; + int ix = HISTORY_INDEX(s->moves[i]); + if(history_tot[ix] > 1024) + { + history_tot[ix] = history_tot[ix]*7/8; + history_hit[ix] = history_hit[ix]*7/8; + } + history_tot[ix] += quiesce ? 8 : 16; } - history_tot[ix] += quiesce ? 8 : 16; - } - if(stack[ply-1].curr_move>=0 && !s->moves[i].capture && - !(s->moves[i].flags>=PROMOTE_FIRST)) - { - int ix = PLUTO_INDEX(stack[ply-1].moves[stack[ply-1].curr_move], s->moves[i]); - if(pluto_tot[ix] > 1024) + if(stack[ply-1].curr_move>=0 && !s->moves[i].capture && + !(s->moves[i].flags>=PROMOTE_FIRST)) { - pluto_tot[ix] = pluto_tot[ix]*7/8; - pluto_hit[ix] = pluto_hit[ix]*7/8; + int ix = PLUTO_INDEX(stack[ply-1].moves[stack[ply-1].curr_move], s->moves[i]); + if(pluto_tot[ix] > 1024) + { + pluto_tot[ix] = pluto_tot[ix]*7/8; + pluto_hit[ix] = pluto_hit[ix]*7/8; + } + pluto_tot[ix] += quiesce ? 8 : 16; } - pluto_tot[ix] += quiesce ? 8 : 16; - } - if(ply>=2 && stack[ply-1].curr_move>=0 && stack[ply-2].curr_move>=0 && !s->moves[i].capture && - !(s->moves[i].flags>=PROMOTE_FIRST)) - { - int ix = PLUTO2_INDEX(stack[ply-2].moves[stack[ply-2].curr_move],stack[ply-1].moves[stack[ply-1].curr_move], s->moves[i]); - if(pluto2_tot[ix] > 1024) + if(ply>=2 && stack[ply-1].curr_move>=0 && stack[ply-2].curr_move>=0 && !s->moves[i].capture && + !(s->moves[i].flags>=PROMOTE_FIRST)) { - pluto2_tot[ix] = pluto2_tot[ix]*7/8; - pluto2_hit[ix] = pluto2_hit[ix]*7/8; + int ix = PLUTO2_INDEX(stack[ply-2].moves[stack[ply-2].curr_move],stack[ply-1].moves[stack[ply-1].curr_move], s->moves[i]); + if(pluto2_tot[ix] > 1024) + { + pluto2_tot[ix] = pluto2_tot[ix]*7/8; + pluto2_hit[ix] = pluto2_hit[ix]*7/8; + } + pluto2_tot[ix] += quiesce ? 8 : 16; } - pluto2_tot[ix] += quiesce ? 8 : 16; } //Set data for pawn-strike #if PAWN_STRIKE if(!quiesce && PIECE_OF(board.data[s->moves[i].from]) == PAWN && s->moves[i].val == 27000) //FIXME, UGLY { - escape_from_1[ply] = s->moves[i].to + Board::up_dir[IS_WHITE(board.color_to_move)] + RIGHT; - if(OUT_OF_BOARD(escape_from_1[ply]) || !IS_OF_COLOR(escape_from_1[ply], board.other_color) - || PIECE_OF(escape_from_1[ply])==PAWN) - escape_from_1[ply] = INVALID; - escape_from_2[ply] = s->moves[i].to + Board::up_dir[IS_WHITE(board.color_to_move)] + LEFT; - if(OUT_OF_BOARD(escape_from_2[ply]) || !IS_OF_COLOR(escape_from_2[ply], board.other_color) - || PIECE_OF(escape_from_2[ply])==PAWN) - escape_from_2[ply] = INVALID; + stack[ply].escape_from[1] = s->moves[i].to + Board::up_dir[IS_WHITE(board.color_to_move)] + RIGHT; + if(OUT_OF_BOARD(stack[ply].escape_from[1]) || !IS_OF_COLOR(board.data[stack[ply].escape_from[1]], board.other_color) + || PIECE_OF(board.data[stack[ply].escape_from[1]])==PAWN) + stack[ply].escape_from[1] = INVALID; + stack[ply].escape_from[2] = s->moves[i].to + Board::up_dir[IS_WHITE(board.color_to_move)] + LEFT; + if(OUT_OF_BOARD(stack[ply].escape_from[2]) || !IS_OF_COLOR(board.data[stack[ply].escape_from[2]], board.other_color) + || PIECE_OF(board.data[stack[ply].escape_from[2]])==PAWN) + stack[ply].escape_from[2] = INVALID; } else { - escape_from_1[ply] = escape_from_2[ply] = INVALID; + stack[ply].escape_from[1] = stack[ply].escape_from[2] = INVALID; } #endif //PAWN_STRIKE s->curr_move = i; @@ -976,7 +991,8 @@ int16_t SearchRoot::search(int ply, int base_depth, bool pv, int16_t orig_alpha, if( (sdepth>0) && !s->under_check && !s->null_threat_dangerous && s->moves[i].val<28000 && (s->moves[i].val<(sdepth<=PLY ? 650 : 450)) ) { - int rdepth = sdepth - PLY; //(s->moves[i].val<300 ? 2*PLY : PLY) - s->moves[i].extend; + int rdepth = depth - 2*PLY; + //sdepth - PLY; //(s->moves[i].val<250 ? 2*PLY : PLY) - s->moves[i].extend; GUI1(notify(s->moves[i], ply, rdepth, s->moves[i].val, alpha, alpha+1, SearchGui::Italic|SearchGui::Gray )); val = -search( ply+1, rdepth, false, -alpha-1, -alpha, false ); GUI2(notify_value(ply, val, DIFF_NODES, val>alpha ? SearchGui::Red : 0)); @@ -1033,27 +1049,30 @@ skip_search: break; } - /* collect statistics for the history */ - if(/*best >= beta &&*/ (best_mv_found!=-1) && - !s->moves[best_mv_found].capture && - !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) - history_hit[HISTORY_INDEX(s->moves[best_mv_found])] += quiesce ? 8 : 16; - - if(stack[ply-1].curr_move>=0 && (best_mv_found!=-1) && - !s->moves[best_mv_found].capture && - !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) + if(!expect_allbad || best >= beta) { - int ix = PLUTO_INDEX(stack[ply-1].moves[stack[ply-1].curr_move], s->moves[best_mv_found]); - pluto_hit[ix] += quiesce ? 8 : 16; - } + /* collect statistics for the history */ + if(/*best >= beta &&*/ (best_mv_found!=-1) && + !s->moves[best_mv_found].capture && + !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) + history_hit[HISTORY_INDEX(s->moves[best_mv_found])] += quiesce ? 8 : 16; + + if(stack[ply-1].curr_move>=0 && (best_mv_found!=-1) && + !s->moves[best_mv_found].capture && + !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) + { + int ix = PLUTO_INDEX(stack[ply-1].moves[stack[ply-1].curr_move], s->moves[best_mv_found]); + pluto_hit[ix] += quiesce ? 8 : 16; + } - if(ply>=2 && stack[ply-1].curr_move>=0 && stack[ply-2].curr_move>=0 && (best_mv_found!=-1) && - !s->moves[best_mv_found].capture && - !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) - { - int ix = PLUTO2_INDEX(stack[ply-2].moves[stack[ply-2].curr_move], - stack[ply-1].moves[stack[ply-1].curr_move], s->moves[best_mv_found]); - pluto2_hit[ix] += quiesce ? 8 : 16; + if(ply>=2 && stack[ply-1].curr_move>=0 && stack[ply-2].curr_move>=0 && (best_mv_found!=-1) && + !s->moves[best_mv_found].capture && + !(s->moves[best_mv_found].flags>=PROMOTE_FIRST) ) + { + int ix = PLUTO2_INDEX(stack[ply-2].moves[stack[ply-2].curr_move], + stack[ply-1].moves[stack[ply-1].curr_move], s->moves[best_mv_found]); + pluto2_hit[ix] += quiesce ? 8 : 16; + } } search_done: @@ -1109,6 +1128,9 @@ Move Engine::find_best_move() s->null_threat_dangerous = false; s->moves = root.mv_stack; s->num_moves = root.mv_stack_top = root.board.find_moves(s->moves); +#if PAWN_STRIKE + s->escape_from[1] = s->escape_from[2] = INVALID; +#endif //PAWN_STRIKE ASSERT(s->moves); -- 2.11.4.GIT