static int full_new_depth(int depth, int move, board_t * board, bool single_reply, bool in_pv, int height, bool extended, bool * cap_extended, int ThreadId) { int new_depth; ASSERT(depth_is_ok(depth)); ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(single_reply==true||single_reply==false); ASSERT(in_pv==true||in_pv==false); ASSERT(depth>0); new_depth = depth - 1; *cap_extended = false; if (in_pv && board->square[MOVE_TO(move)] != Empty && !PIECE_IS_PAWN(board->square[MOVE_TO(move)])){ if ((board->piece_size[White] + board->piece_size[Black]) == 3){ return new_depth+1; } else if ((board->piece_size[White] == 3 && board->piece_size[Black] == 2) || (board->piece_size[White] == 2 && board->piece_size[Black] == 3)) return new_depth+1; } if ((single_reply && ExtendSingleReply) //|| (in_pv && MOVE_TO(move) == board->cap_sq // recapture // && see_move(move,board) >= -100 /*|| ABS(VALUE_PIECE(board->square[MOVE_TO(move)])-VALUE_PIECE(board->square[MOVE_FROM(move)])) <= 250 )*/) //|| (in_pv && PIECE_IS_PAWN(MOVE_PIECE(move,board)) // && (PAWN_RANK(MOVE_TO(move),board->turn) == Rank7 || PAWN_RANK(MOVE_TO(move),board->turn) == Rank6)) //|| (in_pv && board->square[MOVE_TO(move)] != PieceNone256 && SearchCurrent[ThreadId]->act_iteration-height >= 6 && see_move(move,board) >= -100) //|| (in_pv && board->square[MOVE_TO(move)] != PieceNone256 && !extended && see_move(move,board) >= -100) //|| (in_pv && mate_threat == true) || move_is_check(move,board) && (in_pv || see_move(move,board) >= -100)) { // @tried no check extension in endgame (~ -5 elo) // @tried no bad SEE check extension in PV (~ -5 elo) return new_depth+1; } if (in_pv && PIECE_IS_PAWN(MOVE_PIECE(move,board))){ if (is_passed(board,MOVE_TO(move))) return new_depth+1; } if (in_pv && board->square[MOVE_TO(move)] != PieceNone256 && !extended && see_move(move,board) >= -100){ *cap_extended = true; return new_depth+1; } ASSERT(new_depth>=0&&new_depth<=depth); return new_depth; }
static int history_prob(int move, const board_t * board, int ThreadId) { int value; unsigned int index; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(!move_is_tactical(move,board) || see_move(move,board) < 0 || move_is_under_promote(move)); index = history_index(move,board); ASSERT(HistHit[index]<=HistTot[index]); ASSERT(HistTot[index]<HistTotMax); // int * int assumed to be int by C++, large values and overflows need to use double on the interim product. value = int(double(double(HistHit[index]) * HistoryMax) / HistTot[index]); // // for uint16 or short or unsigned short the simple formula is OK. // value = ( ( (HistHit[index]) * HistoryMax) / HistTot[index]); // HistoryMax instead ASSERT(value>=1 && value<=16384); return value; }
static void note_quiet_moves(list_t * list, const board_t * board, bool in_pv, int ThreadId) { int size; int i, move; int move_piece; ASSERT(list_is_ok(list)); ASSERT(board!=NULL); size = LIST_SIZE(list); if (size >= 2) { for (i = 0; i < size; i++) { move = LIST_MOVE(list,i); list->value[i] = quiet_move_value(move,board,ThreadId); if (TryQuietKingAttacks && in_pv) { move_piece = MOVE_PIECE(move,board); if (!(PIECE_IS_PAWN(move_piece) || PIECE_IS_KING(move_piece))) { if (narrow_piece_attack_king(board,move_piece,MOVE_TO(move),KING_POS(board,COLOUR_OPP(board->turn)))) { if (see_move(move,board) >= 0) { // if (1 == NumberThreadsInternal) print_board(board); list->value[i] += 16; } } } } } } }
static bool capture_is_good(int move, const board_t * board) { int piece, capture; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(MOVE_IS_TACTICAL(move,board)); // special cases if (MOVE_IS_EN_PASSANT(move)) return true; if (MOVE_IS_UNDER_PROMOTE(move)) return false; // REMOVE ME? // captures and queen promotes capture = board->square[MOVE_TO(move)]; if (capture != Empty) { // capture ASSERT(move_is_capture(move,board)); if (MOVE_IS_PROMOTE(move)) return true; // promote-capture piece = board->square[MOVE_FROM(move)]; if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true; } return see_move(move,board,0) >= 0; }
bool capture_is_good(int move, const board_t * board, bool in_pv) { #else static bool capture_is_good(int move, const board_t * board, bool in_pv) { #endif int piece, capture; int see_value; // WHM 11/22/08 ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(move_is_tactical(move,board)); // special cases if (MOVE_IS_EN_PASSANT(move)) return true; if (move_is_under_promote(move)) return false; // REMOVE ME? Keep, looks good to me. WHM; // if (MOVE_IS_PROMOTE(move)) return true; // WHM; promote-to-queen, measures a little weaker // too many garbage lines going nuts. // captures and queen promotes capture = board->square[MOVE_TO(move)]; piece = board->square[MOVE_FROM(move)]; if (capture != Empty) { // capture ASSERT(move_is_capture(move,board)); if (MOVE_IS_PROMOTE(move)) return true; // capture a piece on Rank8 and promote to queen if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true; } // return see_move(move,board) >= 0; WHM 11/22/08 // WHM 11/22/08 START see_value = see_move(move,board); if (see_value >= 0) return true; if (TryNodePVQueenPromotes) { if (in_pv && MOVE_IS_PROMOTE(move)) { ASSERT(!move_is_under_promote(move)); return true; // WHM: } } if (TryKingAttackSacs || TryKingBoxSacs || TryPasserSacs) { if (in_pv && see_value > -ValueBishop && capture != Empty) { ASSERT(COLOUR_IS(capture,COLOUR_OPP(board->turn))); // king attack sacs. if (TryKingAttackSacs) { if (narrow_piece_attack_king(board, piece, MOVE_TO(move), KING_POS(board,COLOUR_OPP(board->turn)))) { return true; } } // sacrifice attacks around the narrow/close king box can be examined more fully. Rybka lessons. if (TryKingBoxSacs) { if (DISTANCE(MOVE_TO(move),KING_POS(board,COLOUR_OPP(board->turn))) <= 1) { return true; } } // passer sacrifices... if (TryPasserSacs) { if (PIECE_IS_PAWN(capture) && PAWN_RANK(MOVE_TO(move),COLOUR_OPP(board->turn)) >= Rank6) { return true; } } } } // WHM 11/22/08 END return false; }
int sort_next_qs(sort_t * sort) { int move; int gen; ASSERT(sort!=NULL); while (true) { while (sort->pos < LIST_SIZE(sort->list)) { // next move move = LIST_MOVE(sort->list,sort->pos); sort->pos++; ASSERT(move!=MoveNone); // test if (false) { } else if (sort->test == TEST_LEGAL) { if (!pseudo_is_legal(move,sort->board)) continue; } else if (sort->test == TEST_CAPTURE_QS) { ASSERT(move_is_tactical(move,sort->board)); if (!capture_is_good(move,sort->board,false)) continue; if (!pseudo_is_legal(move,sort->board)) continue; } else if (sort->test == TEST_CHECK_QS) { ASSERT(!move_is_tactical(move,sort->board)); ASSERT(move_is_check(move,sort->board)); if (see_move(move,sort->board) < 0) continue; if (!pseudo_is_legal(move,sort->board)) continue; } else { ASSERT(false); return MoveNone; } ASSERT(pseudo_is_legal(move,sort->board)); return move; } // next stage gen = Code[sort->gen++]; if (false) { } else if (gen == GEN_EVASION_QS) { gen_pseudo_evasions(sort->list,sort->board,sort->attack); note_moves_simple(sort->list,sort->board); list_sort(sort->list); sort->test = TEST_LEGAL; } else if (gen == GEN_CAPTURE_QS) { gen_captures(sort->list,sort->board); note_mvv_lva(sort->list,sort->board); list_sort(sort->list); sort->test = TEST_CAPTURE_QS; } else if (gen == GEN_CHECK_QS) { gen_quiet_checks(sort->list,sort->board); sort->test = TEST_CHECK_QS; } else { ASSERT(gen==GEN_END); return MoveNone; } sort->pos = 0; } }
int sort_next_qs(sort_t * sort) { int move; int gen; ASSERT(sort!=NULL); while (true) { while (sort->pos < LIST_SIZE(sort->list)) { // next move move = LIST_MOVE(sort->list,sort->pos); sort->pos++; ASSERT(move!=MoveNone); // test if (false) { } else if (sort->test == TEST_LEGAL) { if (!pseudo_is_legal(move,sort->board)) continue; } else if (sort->test == TEST_TRANS_KILLER) { if (!move_is_pseudo(move,sort->board)) continue; if (!pseudo_is_legal(move,sort->board)) continue; // check if (!MOVE_IS_TACTICAL(move,sort->board) && (!move_is_check(move,sort->board) || sort->depth < 0)) continue; } else if (sort->test == TEST_CAPTURE_QS) { ASSERT(MOVE_IS_TACTICAL(move,sort->board)); ASSERT(sort->value==NodePV||sort->value==NodeCut||sort->value==NodeAll); if (move == sort->trans_killer) continue; if (sort->value != NodePV && !capture_is_good(move,sort->board)) continue; if (!pseudo_is_legal(move,sort->board)) continue; } else if (sort->test == TEST_CHECK_QS) { ASSERT(!MOVE_IS_TACTICAL(move,sort->board)); ASSERT(move_is_check(move,sort->board)); if (move == sort->trans_killer) continue; if (see_move(move,sort->board,0) < 0) continue; if (!pseudo_is_legal(move,sort->board)) continue; } else { ASSERT(false); return MoveNone; } ASSERT(pseudo_is_legal(move,sort->board)); return move; } // next stage gen = Code[sort->gen++]; if (false) { } else if (gen == GEN_EVASION_QS) { gen_pseudo_evasions(sort->list,sort->board,sort->attack); note_moves_simple(sort->list,sort->board,sort->trans_killer); list_sort(sort->list); sort->test = TEST_LEGAL; } else if (gen == GEN_TRANS) { LIST_CLEAR(sort->list); if (sort->trans_killer != MoveNone) LIST_ADD(sort->list,sort->trans_killer); sort->test = TEST_TRANS_KILLER; } else if (gen == GEN_CAPTURE_QS) { gen_captures(sort->list,sort->board); note_mvv_lva(sort->list,sort->board); list_sort(sort->list); sort->test = TEST_CAPTURE_QS; } else if (gen == GEN_CHECK_QS) { gen_quiet_checks(sort->list,sort->board); sort->test = TEST_CHECK_QS; } else { ASSERT(gen==GEN_END); return MoveNone; } sort->pos = 0; } }