diff --git a/src/endgame.c b/src/endgame.c index e162f77f..383c7db8 100644 --- a/src/endgame.c +++ b/src/endgame.c @@ -162,10 +162,10 @@ static Value EvaluateKXK(const Pos *pos, unsigned strongSide) unsigned weakSide = strongSide ^ 1; assert(verify_material(pos, weakSide, VALUE_ZERO, 0)); - assert(!pos_checkers()); // Eval is never called when in check + assert(!checkers()); // Eval is never called when in check // Stalemate detection with lone king - if (pos_stm() == weakSide) { + if (stm() == weakSide) { ExtMove list[MAX_MOVES]; if (generate_legal(pos, list) == list) return VALUE_DRAW; @@ -186,7 +186,7 @@ static Value EvaluateKXK(const Pos *pos, unsigned strongSide) && (pieces_p(BISHOP) & bb & LightSquares))) result = min(result + VALUE_KNOWN_WIN, VALUE_MATE_IN_MAX_PLY - 1); - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -215,7 +215,7 @@ static Value EvaluateKBNK(const Pos *pos, unsigned strongSide) + PushClose[distance(winnerKSq, loserKSq)] + PushToCorners[loserKSq]; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -232,14 +232,14 @@ static Value EvaluateKPK(const Pos *pos, unsigned strongSide) Square bksq = normalize(pos, strongSide, square_of(weakSide, KING)); Square psq = normalize(pos, strongSide, lsb(pieces_p(PAWN))); - unsigned us = strongSide == pos_stm() ? WHITE : BLACK; + unsigned us = strongSide == stm() ? WHITE : BLACK; if (!bitbases_probe(wksq, psq, bksq, us)) return VALUE_DRAW; Value result = VALUE_KNOWN_WIN + PawnValueEg + (Value)(rank_of(psq)); - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -268,7 +268,7 @@ static Value EvaluateKRKP(const Pos *pos, unsigned strongSide) // If the weaker side's king is too far from the pawn and the rook, // it's a win. - else if ( distance(bksq, psq) >= 3 + (pos_stm() == weakSide) + else if ( distance(bksq, psq) >= 3 + (stm() == weakSide) && distance(bksq, rsq) >= 3) result = RookValueEg - distance(wksq, psq); @@ -277,7 +277,7 @@ static Value EvaluateKRKP(const Pos *pos, unsigned strongSide) else if ( rank_of(bksq) <= RANK_3 && distance(bksq, psq) == 1 && rank_of(wksq) >= RANK_4 - && distance(wksq, psq) > 2 + (pos_stm() == strongSide)) + && distance(wksq, psq) > 2 + (stm() == strongSide)) result = (Value)(80) - 8 * distance(wksq, psq); else @@ -285,7 +285,7 @@ static Value EvaluateKRKP(const Pos *pos, unsigned strongSide) - distance(bksq, psq + SOUTH) - distance(psq, queeningSq)); - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -299,7 +299,7 @@ static Value EvaluateKRKB(const Pos *pos, unsigned strongSide) assert(verify_material(pos, weakSide, BishopValueMg, 0)); Value result = (Value)PushToEdges[square_of(weakSide, KING)]; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -315,7 +315,7 @@ static Value EvaluateKRKN(const Pos *pos, unsigned strongSide) Square bksq = square_of(weakSide, KING); Square bnsq = lsb(pieces_p(KNIGHT)); Value result = (Value)PushToEdges[bksq] + PushAway[distance(bksq, bnsq)]; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -341,7 +341,7 @@ static Value EvaluateKQKP(const Pos *pos, unsigned strongSide) || !((FileABB | FileCBB | FileFBB | FileHBB) & sq_bb(pawnSq))) result += QueenValueEg - PawnValueEg; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -365,7 +365,7 @@ static Value EvaluateKQKR(const Pos *pos, unsigned strongSide) + PushToEdges[loserKSq] + PushClose[distance(winnerKSq, loserKSq)]; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -381,7 +381,7 @@ static Value EvaluateKNNKP(const Pos *pos, unsigned strongSide) - PawnValueEg + PushToEdges[square_of(weakSide, KING)]; - return strongSide == pos_stm() ? result : -result; + return strongSide == stm() ? result : -result; } @@ -512,7 +512,7 @@ static int ScaleKRPKR(const Pos *pos, unsigned strongSide) File f = file_of(wpsq); Rank r = rank_of(wpsq); Square queeningSq = make_square(f, RANK_8); - signed tempo = (pos_stm() == strongSide); + signed tempo = (stm() == strongSide); // If the pawn is not too far advanced and the defending king defends // the queening square, use the third-rank defence. @@ -878,7 +878,7 @@ static int ScaleKPKP(const Pos *pos, unsigned strongSide) Square bksq = normalize(pos, strongSide, square_of(weakSide, KING)); Square psq = normalize(pos, strongSide, square_of(strongSide, PAWN)); - unsigned us = strongSide == pos_stm() ? WHITE : BLACK; + unsigned us = strongSide == stm() ? WHITE : BLACK; // If the pawn has advanced to the fifth rank or further, and is not a // rook pawn, it is too dangerous to assume that it is at least a draw. diff --git a/src/evaluate.c b/src/evaluate.c index 2770badf..ef395248 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -277,19 +277,19 @@ INLINE Score evaluate_piece(const Pos *pos, EvalInfo *ei, Score *mobility, // squares if (more_than_one(attacks_bb_bishop(s, pieces_p(PAWN)) & Center)) score += LongDiagonalBishop; - } - // An important Chess960 pattern: A cornered bishop blocked by a friendly - // pawn diagonally in front of it is a very serious problem, especially - // when that pawn is also blocked. - if ( Pt == BISHOP - && is_chess960() - && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1))) { - Square d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST); - if (piece_on(s + d) == make_piece(Us, PAWN)) - score -= piece_on(s + d + pawn_push(Us)) ? CorneredBishop * 4 - : piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2 - : CorneredBishop; + // An important Chess960 pattern: a cornered bishop blocked by a + // friendly pawn diagonally in front of it is a very serious problem, + // especially when that pawn is also blocked. + if ( is_chess960() + && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1))) + { + Square d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST); + if (piece_on(s + d) == make_piece(Us, PAWN)) + score -= piece_on(s + d + pawn_push(Us)) ? CorneredBishop * 4 + : piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2 + : CorneredBishop; + } } } @@ -709,7 +709,7 @@ INLINE int evaluate_scale_factor(const Pos *pos, EvalInfo *ei, Value eg) sf = 22; else sf = min(sf, 36 + (opposite_bishops(pos) ? 2 : 7) * piece_count(strongSide, PAWN)); - sf = max(0, sf - (pos_rule50_count() - 12) / 4); + sf = max(0, sf - (rule50_count() - 12) / 4); } return sf; @@ -721,7 +721,7 @@ INLINE int evaluate_scale_factor(const Pos *pos, EvalInfo *ei, Value eg) Value evaluate(const Pos *pos) { - assert(!pos_checkers()); + assert(!checkers()); Score mobility[2] = { SCORE_ZERO, SCORE_ZERO }; Value v; @@ -739,7 +739,7 @@ Value evaluate(const Pos *pos) // in the position struct (material + piece square tables) and the // material imbalance. Score is computed internally from the white point // of view. - Score score = pos_psq_score() + material_imbalance(ei.me) + pos->contempt; + Score score = psq_score() + material_imbalance(ei.me) + pos->contempt; // Probe the pawn hash table ei.pe = pawn_probe(pos); @@ -748,7 +748,7 @@ Value evaluate(const Pos *pos) // Early exit if score is high v = (mg_value(score) + eg_value(score)) / 2; if (abs(v) > LazyThreshold + non_pawn_material() / 64) - return pos_stm() == WHITE ? v : -v; + return stm() == WHITE ? v : -v; // Initialize attack and king safety bitboards. evalinfo_init(pos, &ei, WHITE); @@ -789,5 +789,5 @@ Value evaluate(const Pos *pos) v /= PHASE_MIDGAME; - return (pos_stm() == WHITE ? v : -v) + Tempo; // Side to move point of view + return (stm() == WHITE ? v : -v) + Tempo; // Side to move point of view } diff --git a/src/material.h b/src/material.h index 38c695bf..fe753302 100644 --- a/src/material.h +++ b/src/material.h @@ -57,7 +57,7 @@ void material_entry_fill(const Pos *pos, MaterialEntry *e, Key key); INLINE MaterialEntry *material_probe(const Pos *pos) { - Key key = pos_material_key(); + Key key = material_key(); MaterialEntry *e = &pos->materialTable[key >> (64-13)]; if (unlikely(e->key != key)) diff --git a/src/movegen.c b/src/movegen.c index 0b4cdb4e..7399d9ab 100644 --- a/src/movegen.c +++ b/src/movegen.c @@ -246,9 +246,9 @@ INLINE ExtMove *generate_all(const Pos *pos, ExtMove *list, Bitboard target, INLINE ExtMove *generate(const Pos *pos, ExtMove *list, const int Type) { assert(Type == CAPTURES || Type == QUIETS || Type == NON_EVASIONS); - assert(!pos_checkers()); + assert(!checkers()); - Color us = pos_stm(); + Color us = stm(); Bitboard target = Type == CAPTURES ? pieces_c(us ^ 1) : Type == QUIETS ? ~pieces() @@ -280,9 +280,9 @@ ExtMove *generate_non_evasions(const Pos *pos, ExtMove *list) // knight underpromotions that give check. ExtMove *generate_quiet_checks(const Pos *pos, ExtMove *list) { - assert(!pos_checkers()); + assert(!checkers()); - Color us = pos_stm(); + Color us = stm(); Bitboard dc = blockers_for_king(pos, us ^ 1) & pieces_c(us); while (dc) { @@ -310,12 +310,12 @@ ExtMove *generate_quiet_checks(const Pos *pos, ExtMove *list) // side to move is in check. ExtMove *generate_evasions(const Pos *pos, ExtMove *list) { - assert(pos_checkers()); + assert(checkers()); - Color us = pos_stm(); + Color us = stm(); Square ksq = square_of(us, KING); Bitboard sliderAttacks = 0; - Bitboard sliders = pos_checkers() & ~pieces_pp(KNIGHT, PAWN); + Bitboard sliders = checkers() & ~pieces_pp(KNIGHT, PAWN); // Find all the squares attacked by slider checkers. We will remove them // from the king evasions in order to skip known illegal moves, which @@ -330,11 +330,11 @@ ExtMove *generate_evasions(const Pos *pos, ExtMove *list) while (b) (list++)->move = make_move(ksq, pop_lsb(&b)); - if (more_than_one(pos_checkers())) + if (more_than_one(checkers())) return list; // Double check, only a king move can save the day // Generate blocking evasions or captures of the checking piece - Square checksq = lsb(pos_checkers()); + Square checksq = lsb(checkers()); Bitboard target = between_bb(ksq, checksq) | sq_bb(checksq); return us == WHITE ? generate_all(pos, list, target, WHITE, EVASIONS) @@ -346,12 +346,12 @@ ExtMove *generate_evasions(const Pos *pos, ExtMove *list) SMALL ExtMove *generate_legal(const Pos *pos, ExtMove *list) { - Color us = pos_stm(); + Color us = stm(); Bitboard pinned = blockers_for_king(pos, us) & pieces_c(us); Square ksq = square_of(us, KING); ExtMove *cur = list; - list = pos_checkers() ? generate_evasions(pos, list) + list = checkers() ? generate_evasions(pos, list) : generate_non_evasions(pos, list); while (cur != list) if ( (pinned || from_sq(cur->move) == ksq diff --git a/src/movepick.c b/src/movepick.c index a9f61532..e1507d0f 100644 --- a/src/movepick.c +++ b/src/movepick.c @@ -85,7 +85,7 @@ static void score_quiets(const Pos *pos) PieceToHistory *fmh2 = (st-4)->history; PieceToHistory *fmh3 = (st-6)->history; - Color c = pos_stm(); + Color c = stm(); for (ExtMove *m = st->cur; m < st->endMoves; m++) { uint32_t move = m->move & 4095; @@ -107,7 +107,7 @@ static void score_evasions(const Pos *pos) ButterflyHistory *history = pos->history; PieceToHistory *cmh = (st-1)->history; - Color c = pos_stm(); + Color c = stm(); for (ExtMove *m = st->cur; m < st->endMoves; m++) if (is_capture(pos, m->move)) diff --git a/src/movepick.h b/src/movepick.h index 61dbb55e..8cda9e99 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -77,7 +77,7 @@ INLINE void mp_init(const Pos *pos, Move ttm, Depth d) st->mpKillers[0] = st->killers[0]; st->mpKillers[1] = st->killers[1]; - st->stage = pos_checkers() ? ST_EVASION : ST_MAIN_SEARCH; + st->stage = checkers() ? ST_EVASION : ST_MAIN_SEARCH; st->ttMove = ttm; if (!ttm || !is_pseudo_legal(pos, ttm)) { st->stage++; @@ -91,7 +91,7 @@ INLINE void mp_init_q(const Pos *pos, Move ttm, Depth d, Square s) Stack *st = pos->st; - st->stage = pos_checkers() ? ST_EVASION : ST_QSEARCH; + st->stage = checkers() ? ST_EVASION : ST_QSEARCH; st->ttMove = ttm && is_pseudo_legal(pos, ttm) && (d > DEPTH_QS_RECAPTURES || to_sq(ttm) == s) ? ttm : 0; @@ -103,7 +103,7 @@ INLINE void mp_init_q(const Pos *pos, Move ttm, Depth d, Square s) INLINE void mp_init_pc(const Pos *pos, Move ttm, Value th) { - assert(!pos_checkers()); + assert(!checkers()); Stack *st = pos->st; diff --git a/src/ntsearch.c b/src/ntsearch.c index 098cbf57..8a706065 100644 --- a/src/ntsearch.c +++ b/src/ntsearch.c @@ -39,10 +39,10 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // Dive into quiescense search when the depth reaches zero if (depth < 1) return PvNode - ? pos_checkers() + ? checkers() ? qsearch_PV_true(pos, ss, alpha, beta, 0) : qsearch_PV_false(pos, ss, alpha, beta, 0) - : pos_checkers() + : checkers() ? qsearch_NonPV_true(pos, ss, alpha, 0) : qsearch_NonPV_false(pos, ss, alpha, 0); @@ -64,7 +64,7 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) int moveCount, captureCount, quietCount; // Step 1. Initialize node - inCheck = !!pos_checkers(); + inCheck = !!checkers(); moveCount = captureCount = quietCount = ss->moveCount = 0; bestValue = -VALUE_INFINITE; maxValue = VALUE_INFINITE; @@ -127,12 +127,12 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // use a different position key in case of an excluded move. excludedMove = ss->excludedMove; #ifdef BIG_TT - posKey = pos_key() ^ (Key)excludedMove; + posKey = key() ^ (Key)excludedMove; #else - posKey = pos_key() ^ (Key)((int32_t)excludedMove << 16); + posKey = key() ^ (Key)((int32_t)excludedMove << 16); #endif tte = tt_probe(posKey, &ttHit); - ttValue = ttHit ? value_from_tt(tte_value(tte), ss->ply, pos_rule50_count()) : VALUE_NONE; + ttValue = ttHit ? value_from_tt(tte_value(tte), ss->ply, rule50_count()) : VALUE_NONE; ttMove = rootNode ? pos->rootMoves->move[pos->pvIdx].pv[0] : ttHit ? tte_move(tte) : 0; ttPv = PvNode ? 4 : (ttHit ? tte_is_pv(tte) : 0); @@ -162,11 +162,11 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // Penalty for a quiet ttMove that fails low else if (!is_capture_or_promotion(pos, ttMove)) { Value penalty = -stat_bonus(depth); - history_update(*pos->history, pos_stm(), ttMove, penalty); + history_update(*pos->history, stm(), ttMove, penalty); update_cm_stats(ss, moved_piece(ttMove), to_sq(ttMove), penalty); } } - if (pos_rule50_count() < 90) + if (rule50_count() < 90) return ttValue; } @@ -176,7 +176,7 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) if ( piecesCnt <= TB_Cardinality && (piecesCnt < TB_Cardinality || depth >= TB_ProbeDepth) - && pos_rule50_count() == 0 + && rule50_count() == 0 && !can_castle_any()) { int found, wdl = TB_probe_wdl(pos, &found); @@ -280,7 +280,7 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) && eval >= ss->staticEval && ss->staticEval >= beta - 32 * depth + 292 - improving * 30 && !excludedMove - && non_pawn_material_c(pos_stm()) + && non_pawn_material_c(stm()) && (ss->ply >= pos->nmpPly || ss->ply % 2 != pos->nmpOdd)) { assert(eval - beta >= 0); @@ -434,7 +434,7 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // Step 13. Pruning at shallow depth if ( !rootNode - && non_pawn_material_c(pos_stm()) + && non_pawn_material_c(stm()) && bestValue > VALUE_MATED_IN_MAX_PLY) { // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold @@ -455,11 +455,11 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // Futility pruning: parent node if ( lmrDepth < 6 && !inCheck - && ss->staticEval + 255 + 182 * lmrDepth <= alpha - && (*pos->history)[pos_stm()][from_to(move)] + && ss->staticEval + 235 + 172 * lmrDepth <= alpha + && (*pos->history)[stm()][from_to(move)] + (*cmh )[movedPiece][to_sq(move)] + (*fmh )[movedPiece][to_sq(move)] - + (*fmh2)[movedPiece][to_sq(move)] < 30000) + + (*fmh2)[movedPiece][to_sq(move)] < 25000) continue; // Prune moves with negative SEE at low depths and below a decreasing @@ -518,13 +518,13 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) ss->mpKillers[0] = k1; ss->mpKillers[1] = k2; } else if ( givesCheck - && (is_discovery_check_on_king(pos, pos_stm() ^ 1, move) || see_test(pos, move, 0))) + && (is_discovery_check_on_king(pos, stm() ^ 1, move) || see_test(pos, move, 0))) extension = 1; // Passed pawn extension else if ( move == ss->killers[0] && advanced_pawn_push(pos, move) - && pawn_passed(pos, pos_stm(), to_sq(move))) + && pawn_passed(pos, stm(), to_sq(move))) extension = 1; // Last captures extension @@ -561,7 +561,7 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) // Step 16. Reduced depth search (LMR). If the move fails high it will be // re-searched at full depth. if ( depth >= 3 - && moveCount > 1 + 2 * rootNode + && moveCount > 1 + rootNode + (rootNode && bestValue < alpha) && (!rootNode || best_move_count(pos, move) == 0) && ( !captureOrPromotion || moveCountPruning @@ -607,14 +607,14 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) ss->statScore = (*cmh )[movedPiece][to_sq(move)] + (*fmh )[movedPiece][to_sq(move)] + (*fmh2)[movedPiece][to_sq(move)] - + (*pos->history)[pos_stm() ^ 1][from_to(move)] + + (*pos->history)[stm() ^ 1][from_to(move)] - 4926; // Reset statScore if negative and most stats show >= 0 if ( ss->statScore < 0 && (*cmh )[movedPiece][to_sq(move)] >= 0 && (*fmh )[movedPiece][to_sq(move)] >= 0 - && (*pos->history)[pos_stm() ^ 1][from_to(move)] >= 0) + && (*pos->history)[stm() ^ 1][from_to(move)] >= 0) ss->statScore = 0; // Decrease/increase reduction by comparing with opponent's stat score. @@ -628,7 +628,12 @@ Value search_NonPV(Pos *pos, Stack *ss, Value alpha, Depth depth, int cutNode) r -= ss->statScore / 16384; } - Depth d = max(newDepth - max(r, 0), 1); + // Increase reduction for captures/promotions if late move and at low + // depth + else if (depth < 8 && moveCount > 2) + r++; + + Depth d = clamp(newDepth - r, 1, newDepth); value = -search_NonPV(pos, ss+1, -(alpha+1), d, 1); diff --git a/src/pawns.h b/src/pawns.h index a5b55336..fe9a6f70 100644 --- a/src/pawns.h +++ b/src/pawns.h @@ -60,7 +60,7 @@ void pawn_entry_fill(const Pos *pos, PawnEntry *e, Key k); INLINE PawnEntry *pawn_probe(const Pos *pos) { - Key key = pos_pawn_key(); + Key key = pawn_key(); PawnEntry *e = &pos->pawnTable[key & (PAWN_ENTRIES - 1)]; if (unlikely(e->key != key)) diff --git a/src/polybook.c b/src/polybook.c index e85d37c6..62559f35 100644 --- a/src/polybook.c +++ b/src/polybook.c @@ -444,7 +444,7 @@ static Key polyglot_key(const Pos *pos) if (ep_square()) key ^= PG.Zobrist.enpassant[file_of(ep_square())]; - if (pos_stm() == WHITE) + if (stm() == WHITE) key ^= PG.Zobrist.turn; return key; @@ -572,7 +572,7 @@ static bool check_do_search(const Pos *pos) || akt_position == last_position || akt_anz_pieces > last_anz_pieces || akt_anz_pieces < last_anz_pieces - 2 - || pos_key() == 0xB4D30CD15A43432D; + || key() == 0xB4D30CD15A43432D; // Reset do_search and book depth counter if postion changed more // than one move can do or in initial position diff --git a/src/position.c b/src/position.c index bbc63ee2..a6523e50 100644 --- a/src/position.c +++ b/src/position.c @@ -98,7 +98,7 @@ INLINE void set_check_info(Pos *pos) st->blockersForKing[WHITE] = slider_blockers(pos, pieces_c(BLACK), square_of(WHITE, KING), &st->pinnersForKing[WHITE]); st->blockersForKing[BLACK] = slider_blockers(pos, pieces_c(WHITE), square_of(BLACK, KING), &st->pinnersForKing[BLACK]); - Color them = pos_stm() ^ 1; + Color them = stm() ^ 1; st->ksq = square_of(them, KING); st->checkSquares[PAWN] = attacks_from_pawn(st->ksq, them); @@ -127,10 +127,10 @@ void print_pos(Pos *pos) printf(" |\n +---+---+---+---+---+---+---+---+\n"); } - printf("\nFen: %s\nKey: %16"PRIX64"\nCheckers: ", fen, pos_key()); + printf("\nFen: %s\nKey: %16"PRIX64"\nCheckers: ", fen, key()); char buf[16]; - for (Bitboard b = pos_checkers(); b; ) + for (Bitboard b = checkers(); b; ) printf("%s ", uci_square(buf, pop_lsb(&b))); if (popcount(pieces()) <= TB_MaxCardinality && !can_castle_cr(ANY_CASTLING)) { @@ -301,7 +301,7 @@ void pos_set(Pos *pos, char *fen, int isChess960) { st->epSquare = make_square(col - 'a', row - '1'); - if (!(attackers_to(st->epSquare) & pieces_cp(pos_stm(), PAWN))) + if (!(attackers_to(st->epSquare) & pieces_cp(stm(), PAWN))) st->epSquare = 0; } else @@ -313,7 +313,7 @@ void pos_set(Pos *pos, char *fen, int isChess960) // Convert from fullmove starting from 1 to ply starting from 0, // handle also common incorrect FEN with fullmove = 0. - pos->gamePly = max(2 * (pos->gamePly - 1), 0) + (pos_stm() == BLACK); + pos->gamePly = max(2 * (pos->gamePly - 1), 0) + (stm() == BLACK); pos->chess960 = isChess960; set_state(pos, st); @@ -384,7 +384,7 @@ static void set_state(Pos *pos, Stack *st) st->nonPawn = 0; st->psq = 0; - st->checkersBB = attackers_to(square_of(pos_stm(), KING)) & pieces_c(pos_stm() ^ 1); + st->checkersBB = attackers_to(square_of(stm(), KING)) & pieces_c(stm() ^ 1); set_check_info(pos); @@ -398,7 +398,7 @@ static void set_state(Pos *pos, Stack *st) if (st->epSquare != 0) st->key ^= zob.enpassant[file_of(st->epSquare)]; - if (pos_stm() == BLACK) + if (stm() == BLACK) st->key ^= zob.side; st->key ^= zob.castling[st->castlingRights]; @@ -437,7 +437,7 @@ void pos_fen(const Pos *pos, char *str) } *str++ = ' '; - *str++ = pos_stm() == WHITE ? 'w' : 'b'; + *str++ = stm() == WHITE ? 'w' : 'b'; *str++ = ' '; int cr = pos->st->castlingRights; @@ -464,8 +464,8 @@ void pos_fen(const Pos *pos, char *str) *str++ = '-'; } - sprintf(str, " %d %d", pos_rule50_count(), - 1 + (pos_game_ply() - (pos_stm() == BLACK)) / 2); + sprintf(str, " %d %d", rule50_count(), + 1 + (game_ply() - (stm() == BLACK)) / 2); } @@ -509,7 +509,7 @@ Bitboard slider_blockers(const Pos *pos, Bitboard sliders, Square s, // attackers_to() computes a bitboard of all pieces which attack a given // square. Slider attacks use the occupied bitboard to indicate occupancy. -Bitboard pos_attackers_to_occ(const Pos *pos, Square s, Bitboard occupied) +Bitboard attackers_to_occ(const Pos *pos, Square s, Bitboard occupied) { return (attacks_from_pawn(s, BLACK) & pieces_cp(WHITE, PAWN)) | (attacks_from_pawn(s, WHITE) & pieces_cp(BLACK, PAWN)) @@ -527,7 +527,7 @@ int is_legal(const Pos *pos, Move m) { assert(move_is_ok(m)); - uint64_t us = pos_stm(); + uint64_t us = stm(); Square from = from_sq(m); Square to = to_sq(m); @@ -588,7 +588,7 @@ int is_legal(const Pos *pos, Move m) #if 0 int is_pseudo_legal_old(Pos *pos, Move m) { - int us = pos_stm(); + int us = stm(); Square from = from_sq(m); Square to = to_sq(m); Piece pc = moved_piece(m); @@ -637,19 +637,19 @@ int is_pseudo_legal_old(Pos *pos, Move m) // Evasions generator already takes care to avoid some kind of illegal moves // and legal() relies on this. We therefore have to take care that the same // kind of moves are filtered out here. - if (pos_checkers()) { + if (checkers()) { if (type_of_p(pc) != KING) { // Double check? In this case a king move is required - if (more_than_one(pos_checkers())) + if (more_than_one(checkers())) return 0; // Our move must be a blocking evasion or a capture of the checking piece - if (!((between_bb(lsb(pos_checkers()), square_of(us, KING)) | pos_checkers()) & sq_bb(to))) + if (!((between_bb(lsb(checkers()), square_of(us, KING)) | checkers()) & sq_bb(to))) return 0; } // In case of king moves under check we have to remove king so as to catch // invalid moves like b1a1 when opposite queen is on c1. - else if (attackers_to_occ(to, pieces() ^ sq_bb(from)) & pieces_c(us ^ 1)) + else if (attackers_to_occ(pos, to, pieces() ^ sq_bb(from)) & pieces_c(us ^ 1)) return 0; } @@ -659,14 +659,14 @@ int is_pseudo_legal_old(Pos *pos, Move m) int is_pseudo_legal(const Pos *pos, Move m) { - uint64_t us = pos_stm(); + uint64_t us = stm(); Square from = from_sq(m); if (!(pieces_c(us) & sq_bb(from))) return 0; if (unlikely(type_of_m(m) == CASTLING)) { - if (pos_checkers()) return 0; + if (checkers()) return 0; ExtMove list[MAX_MOVES]; ExtMove *end = generate_quiets(pos, list); for (ExtMove *p = list; p < end; p++) @@ -705,8 +705,8 @@ int is_pseudo_legal(const Pos *pos, Move m) // is_legal() does not remove the "from" square from the "occupied" // bitboard when checking that the king is not in check on the "to" // square. So we need to be careful here. - if ( pos_checkers() - && (attackers_to_occ(to, pieces() ^ sq_bb(from)) & pieces_c(us ^ 1))) + if ( checkers() + && (attackers_to_occ(pos, to, pieces() ^ sq_bb(from)) & pieces_c(us ^ 1))) return 0; return 1; default: @@ -733,12 +733,12 @@ int is_pseudo_legal(const Pos *pos, Move m) else return to == ep_square() && (attacks_from_pawn(from, us) & sq_bb(to)); } - if (pos_checkers()) { + if (checkers()) { // Again we need to be a bit careful. - if (more_than_one(pos_checkers())) + if (more_than_one(checkers())) return 0; - if (!((between_bb(lsb(pos_checkers()), square_of(us, KING)) - | pos_checkers()) & sq_bb(to))) + if (!((between_bb(lsb(checkers()), square_of(us, KING)) + | checkers()) & sq_bb(to))) return 0; } return 1; @@ -766,12 +766,12 @@ exit(1); int gives_check_special(const Pos *pos, Stack *st, Move m) { assert(move_is_ok(m)); - assert(color_of(moved_piece(m)) == pos_stm()); + assert(color_of(moved_piece(m)) == stm()); Square from = from_sq(m); Square to = to_sq(m); - if ((blockers_for_king(pos, pos_stm() ^ 1) & sq_bb(from)) && !aligned(m, st->ksq)) + if ((blockers_for_king(pos, stm() ^ 1) & sq_bb(from)) && !aligned(m, st->ksq)) return 1; switch (type_of_m(m)) { @@ -789,14 +789,14 @@ int gives_check_special(const Pos *pos, Stack *st, Move m) Square capsq = make_square(file_of(to), rank_of(from)); // Bitboard b = pieces() ^ sq_bb(from) ^ sq_bb(capsq) ^ sq_bb(to); Bitboard b = inv_sq(inv_sq(inv_sq(pieces(), from), to), capsq); - return (attacks_bb_rook (st->ksq, b) & pieces_cpp(pos_stm(), QUEEN, ROOK)) - ||(attacks_bb_bishop(st->ksq, b) & pieces_cpp(pos_stm(), QUEEN, BISHOP)); + return (attacks_bb_rook (st->ksq, b) & pieces_cpp(stm(), QUEEN, ROOK)) + ||(attacks_bb_bishop(st->ksq, b) & pieces_cpp(stm(), QUEEN, BISHOP)); } case CASTLING: { #ifdef PEDANTIC // Castling is encoded as 'King captures the rook' - Square rto = relative_square(pos_stm(), to > from ? SQ_F1 : SQ_D1); + Square rto = relative_square(stm(), to > from ? SQ_F1 : SQ_D1); #else Square rto = CastlingRookTo[to & 0x0f]; #endif @@ -968,7 +968,7 @@ void do_move(Pos *pos, Move m, int givesCheck) { assert(move_is_ok(m)); - Key key = pos_key() ^ zob.side; + Key key = key() ^ zob.side; // Copy some fields of the old state to our new Stack object except the // ones which are going to be recalculated from scratch anyway and then @@ -981,7 +981,7 @@ void do_move(Pos *pos, Move m, int givesCheck) // on in case of a capture or a pawn move. st->plyCounters += 0x101; // Increment both rule50 and pliesFromNull - Color us = pos_stm(); + Color us = stm(); Color them = us ^ 1; Square from = from_sq(m); Square to = to_sq(m); @@ -1155,7 +1155,7 @@ void undo_move(Pos *pos, Move m) pos->sideToMove ^= 1; - Color us = pos_stm(); + Color us = stm(); Square from = from_sq(m); Square to = to_sq(m); Piece piece = piece_on(to); @@ -1220,7 +1220,7 @@ void undo_move(Pos *pos, Move m) void do_null_move(Pos *pos) { - assert(!pos_checkers()); + assert(!checkers()); Stack *st = ++pos->st; memcpy(st, st - 1, (StateSize + 7) & ~7); @@ -1256,7 +1256,7 @@ Key key_after(const Pos *pos, Move m) Square to = to_sq(m); Piece pc = piece_on(from); Piece captured = piece_on(to); - Key k = pos_key() ^ zob.side; + Key k = key() ^ zob.side; if (captured) k ^= zob.psq[captured][to]; @@ -1284,7 +1284,7 @@ int see_test(const Pos *pos, Move m, int value) occ = pieces() ^ sq_bb(from) ^ sq_bb(to); Color stm = color_of(piece_on(from)); - Bitboard attackers = attackers_to_occ(to, occ), stmAttackers; + Bitboard attackers = attackers_to_occ(pos, to, occ), stmAttackers; int res = 1; while (1) { @@ -1339,7 +1339,7 @@ int is_draw(const Pos *pos) Stack *st = pos->st; if (unlikely(st->rule50 > 99)) { - if (!pos_checkers()) + if (!checkers()) return 1; return generate_legal(pos, (st-1)->endMoves) != (st-1)->endMoves; } @@ -1381,7 +1381,7 @@ bool has_game_cycle(const Pos *pos, int ply) { Move m = cuckooMove[j]; if (!(((Bitboard *)BetweenBB)[m] & pieces())) { if ( ply > i - || color_of(piece_on(is_empty(from_sq(m)) ? to_sq(m) : from_sq(m))) == pos_stm()) + || color_of(piece_on(is_empty(from_sq(m)) ? to_sq(m) : from_sq(m))) == stm()) return true; } } @@ -1411,17 +1411,17 @@ static int pos_is_ok(Pos *pos, int *failedStep) *failedStep = step; if (step == Default) - if ( (pos_stm() != WHITE && pos_stm() != BLACK) + if ( (stm() != WHITE && stm() != BLACK) || piece_on(square_of(WHITE, KING)) != W_KING || piece_on(square_of(BLACK, KING)) != B_KING - || ( ep_square() && relative_rank_s(pos_stm(), ep_square()) != RANK_6)) + || ( ep_square() && relative_rank_s(stm(), ep_square()) != RANK_6)) return 0; #if 0 if (step == King) if ( std::count(board, board + SQUARE_NB, W_KING) != 1 || std::count(board, board + SQUARE_NB, B_KING) != 1 - || attackers_to(square_of(pos_stm() ^ 1, KING)) & pieces_c(pos_stm())) + || attackers_to(square_of(stm() ^ 1, KING)) & pieces_c(stm())) return 0; #endif diff --git a/src/position.h b/src/position.h index 6b45d53e..d0e9790a 100644 --- a/src/position.h +++ b/src/position.h @@ -190,7 +190,7 @@ void pos_set(Pos *pos, char *fen, int isChess960); void pos_fen(const Pos *pos, char *fen); void print_pos(Pos *pos); -//PURE Bitboard pos_attackers_to_occ(const Pos *pos, Square s, Bitboard occupied); +//PURE Bitboard attackers_to_occ(const Pos *pos, Square s, Bitboard occupied); PURE Bitboard slider_blockers(const Pos *pos, Bitboard sliders, Square s, Bitboard *pinners); @@ -236,7 +236,7 @@ PURE bool has_game_cycle(const Pos *pos, int ply); Bitboard pcs = pieces_cp(c,p); \ while (pcs && (s = pop_lsb(&pcs), 1)) #endif -#define piece_count_mk(c, p) (((pos_material_key()) >> (20 * (c) + 4 * (p) + 4)) & 15) +#define piece_count_mk(c, p) (((material_key()) >> (20 * (c) + 4 * (p) + 4)) & 15) // Castling #define can_castle_cr(cr) (pos->st->castlingRights & (cr)) @@ -251,11 +251,10 @@ PURE bool has_game_cycle(const Pos *pos, int ply); #endif // Checking -#define pos_checkers() (pos->st->checkersBB) +#define checkers() (pos->st->checkersBB) // Attacks to/from a given square -#define attackers_to_occ(s,occ) pos_attackers_to_occ(pos,s,occ) -#define attackers_to(s) attackers_to_occ(s,pieces()) +#define attackers_to(s) attackers_to_occ(pos,s,pieces()) #define attacks_from_pawn(s,c) (PawnAttacks[c][s]) #define attacks_from_knight(s) (PseudoAttacks[KNIGHT][s]) #define attacks_from_bishop(s) attacks_bb_bishop(s, pieces()) @@ -269,20 +268,20 @@ PURE bool has_game_cycle(const Pos *pos, int ply); #define captured_piece() (pos->st->capturedPiece) // Accessing hash keys -#define pos_key() (pos->st->key) -#define pos_material_key() (pos->st->materialKey) -#define pos_pawn_key() (pos->st->pawnKey) +#define key() (pos->st->key) +#define material_key() (pos->st->materialKey) +#define pawn_key() (pos->st->pawnKey) // Other properties of the position -#define pos_stm() (pos->sideToMove) -#define pos_game_ply() (pos->gamePly) +#define stm() (pos->sideToMove) +#define game_ply() (pos->gamePly) #define is_chess960() (pos->chess960) -#define pos_nodes_searched() (pos->nodes) -#define pos_rule50_count() (pos->st->rule50) -#define pos_psq_score() (pos->st->psq) +#define nodes_searched() (pos->nodes) +#define rule50_count() (pos->st->rule50) +#define psq_score() (pos->st->psq) #define non_pawn_material_c(c) (pos->st->nonPawnMaterial[c]) #define non_pawn_material() (non_pawn_material_c(WHITE) + non_pawn_material_c(BLACK)) -#define pos_pawns_only() (!pos->st->nonPawn) +#define pawns_only() (!pos->st->nonPawn) INLINE Bitboard blockers_for_king(const Pos *pos, uint32_t c) { @@ -302,7 +301,7 @@ INLINE int pawn_passed(const Pos *pos, uint32_t c, Square s) INLINE int advanced_pawn_push(const Pos *pos, Move m) { return type_of_p(moved_piece(m)) == PAWN - && relative_rank_s(pos_stm(), from_sq(m)) > RANK_4; + && relative_rank_s(stm(), from_sq(m)) > RANK_4; } INLINE int opposite_bishops(const Pos *pos) @@ -312,7 +311,7 @@ INLINE int opposite_bishops(const Pos *pos) && piece_count(BLACK, BISHOP) == 1 && opposite_colors(square_of(WHITE, BISHOP), square_of(BLACK, BISHOP)); #elif 0 - return (pos_material_key() & 0xf0000f0000) == 0x1000010000 + return (material_key() & 0xf0000f0000) == 0x1000010000 && (pieces_p(BISHOP) & DarkSquares) && (pieces_p(BISHOP) & DarkSquares) != pieces_p(BISHOP); #else @@ -338,7 +337,7 @@ INLINE int is_capture(const Pos *pos, Move m) INLINE int gives_check(const Pos *pos, Stack *st, Move m) { - return type_of_m(m) == NORMAL && !(blockers_for_king(pos, pos_stm() ^ 1) & pieces_c(pos_stm())) + return type_of_m(m) == NORMAL && !(blockers_for_king(pos, stm() ^ 1) & pieces_c(stm())) ? !!(st->checkSquares[type_of_p(moved_piece(m))] & sq_bb(to_sq(m))) : gives_check_special(pos, st, m); } @@ -349,7 +348,7 @@ void pos_set_check_info(Pos *pos); INLINE void undo_null_move(Pos *pos) { - assert(!pos_checkers()); + assert(!checkers()); pos->st--; pos->sideToMove ^= 1; @@ -391,8 +390,7 @@ INLINE Bitboard slider_blockers(const Pos *pos, Bitboard sliders, Square s, // attackers_to() computes a bitboard of all pieces which attack a given // square. Slider attacks use the occupied bitboard to indicate occupancy. -INLINE Bitboard pos_attackers_to_occ(const Pos *pos, Square s, - Bitboard occupied) +INLINE Bitboard attackers_to_occ(const Pos *pos, Square s, Bitboard occupied) { return (attacks_from_pawn(s, BLACK) & pieces_cp(WHITE, PAWN)) | (attacks_from_pawn(s, WHITE) & pieces_cp(BLACK, PAWN)) diff --git a/src/qsearch.c b/src/qsearch.c index 67eff200..16bf3500 100644 --- a/src/qsearch.c +++ b/src/qsearch.c @@ -22,7 +22,7 @@ Value name_NT_InCheck(qsearch)(Pos* pos, Stack* ss, Value alpha, BETA_ARG Depth depth) { - assert(InCheck == !!pos_checkers()); + assert(InCheck == !!checkers()); assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE); assert(PvNode || (alpha == beta - 1)); assert(depth <= 0); @@ -58,9 +58,9 @@ Value name_NT_InCheck(qsearch)(Pos* pos, Stack* ss, Value alpha, BETA_ARG : DEPTH_QS_NO_CHECKS; // Transposition table lookup - posKey = pos_key(); + posKey = key(); tte = tt_probe(posKey, &ttHit); - ttValue = ttHit ? value_from_tt(tte_value(tte), ss->ply, pos_rule50_count()) : VALUE_NONE; + ttValue = ttHit ? value_from_tt(tte_value(tte), ss->ply, rule50_count()) : VALUE_NONE; ttMove = ttHit ? tte_move(tte) : 0; ttPv = ttHit ? tte_is_pv(tte) : 0; diff --git a/src/search.c b/src/search.c index 75f180a6..81c1931d 100644 --- a/src/search.c +++ b/src/search.c @@ -221,8 +221,8 @@ uint64_t perft(Pos *pos, Depth depth) void mainthread_search(void) { Pos *pos = Threads.pos[0]; - int us = pos_stm(); - time_init(us, pos_game_ply()); + int us = stm(); + time_init(us, game_ply()); tt_new_search(); char buf[16]; bool playBookMove = false; @@ -290,7 +290,7 @@ void mainthread_search(void) pos->rootMoves->move[0].pvSize = 1; pos->rootMoves->size++; printf("info depth 0 score %s\n", - uci_value(buf, pos_checkers() ? -VALUE_MATE : VALUE_DRAW)); + uci_value(buf, checkers() ? -VALUE_MATE : VALUE_DRAW)); fflush(stdout); } @@ -412,6 +412,7 @@ void thread_search(Pos *pos) RootMoves *rm = pos->rootMoves; multiPV = min(multiPV, rm->size); pos->ttHitAverage = ttHitAverageWindow * ttHitAverageResolution / 2; + int searchAgainCounter = 0; // Iterative deepening loop until requested to stop or the target depth // is reached. @@ -430,11 +431,14 @@ void thread_search(Pos *pos) for (int idx = 0; idx < rm->size; idx++) rm->move[idx].previousScore = rm->move[idx].score; - pos->contempt = pos_stm() == WHITE ? make_score(base_ct, base_ct / 2) - : -make_score(base_ct, base_ct / 2); + pos->contempt = stm() == WHITE ? make_score(base_ct, base_ct / 2) + : -make_score(base_ct, base_ct / 2); int pvFirst = 0, pvLast = 0; + if (!Threads.increaseDepth) + searchAgainCounter++; + // MultiPV loop. We perform a full root search for each PV line for (int pvIdx = 0; pvIdx < multiPV && !Signals.stop; pvIdx++) { pos->pvIdx = pvIdx; @@ -465,8 +469,8 @@ void thread_search(Pos *pos) // Adjust contempt based on root move's previousScore int ct = base_ct + (102 - base_ct / 2) * previousScore / (abs(previousScore) + 157); - pos->contempt = pos_stm() == WHITE ? make_score(ct, ct / 2) - : -make_score(ct, ct / 2); + pos->contempt = stm() == WHITE ? make_score(ct, ct / 2) + : -make_score(ct, ct / 2); } // Start with a small aspiration window and, in the case of a fail @@ -474,7 +478,7 @@ void thread_search(Pos *pos) // high/low anymore. int failedHighCnt = 0; while (true) { - Depth adjustedDepth = max(1, pos->rootDepth - failedHighCnt); + Depth adjustedDepth = max(1, pos->rootDepth - failedHighCnt - searchAgainCounter); bestValue = search_PV(pos, ss, alpha, beta, adjustedDepth); // Bring the best move to the front. It is critical that sorting @@ -585,7 +589,12 @@ void thread_search(Pos *pos) Signals.stopOnPonderhit = 1; else Signals.stop = 1; - } + } else if (Threads.increaseDepth + && !Limits.ponder + && time_elapsed() > time_optimum() * fallingEval * reduction * bestMoveInstability * 0.6) + Threads.increaseDepth = false; + else + Threads.increaseDepth = true; } mainThread.iterValue[iterIdx] = bestValue; @@ -628,9 +637,6 @@ static int best_move_count(Pos *pos, Move move) // search function when the remaining depth is zero (or, to be more precise, // less than one). -#define true 1 -#define false 0 - #define NT PV #define InCheck false #include "qsearch.c" @@ -648,9 +654,6 @@ static int best_move_count(Pos *pos, Move move) #undef InCheck #undef NT -#undef true -#undef false - #define rm_lt(m1,m2) ((m1).tbRank != (m2).tbRank ? (m1).tbRank < (m2).tbRank : (m1).score != (m2).score ? (m1).score < (m2).score : (m1).previousScore < (m2).previousScore) // stable_sort() sorts RootMoves from highest-scoring move to lowest-scoring @@ -752,7 +755,7 @@ static void update_stats(const Pos *pos, Stack *ss, Move move, Move *quiets, ss->killers[0] = move; } - int c = pos_stm(); + int c = stm(); history_update(*pos->history, c, move, bonus); update_cm_stats(ss, moved_piece(move), to_sq(move), bonus); @@ -900,7 +903,7 @@ static int extract_ponder_from_tt(RootMove *rm, Pos *pos) return 0; do_move(pos, rm->pv[0], gives_check(pos, pos->st, rm->pv[0])); - TTEntry *tte = tt_probe(pos_key(), &ttHit); + TTEntry *tte = tt_probe(key(), &ttHit); if (ttHit) { Move m = tte_move(tte); // Local copy to be SMP safe @@ -975,6 +978,7 @@ void start_thinking(Pos *root) thread_wait_until_sleeping(threads_main()); Signals.stopOnPonderhit = Signals.stop = 0; + Threads.increaseDepth = true; // Generate all legal moves. ExtMove list[MAX_MOVES]; diff --git a/src/tbprobe.c b/src/tbprobe.c index 0978c245..79f3334b 100644 --- a/src/tbprobe.c +++ b/src/tbprobe.c @@ -1169,7 +1169,7 @@ INLINE int fill_squares(Pos *pos, uint8_t *pc, bool flip, int mirror, int *p, INLINE int probe_table(Pos *pos, int s, int *success, const int type) { // Obtain the position's material-signature key - Key key = pos_material_key(); + Key key = material_key(); // Test for KvK if (type == WDL && key == 2ULL) @@ -1209,13 +1209,13 @@ INLINE int probe_table(Pos *pos, int s, int *success, const int type) bool bside, flip; if (!be->symmetric) { flip = key != be->key; - bside = (pos_stm() == WHITE) == flip; + bside = (stm() == WHITE) == flip; if (type == DTM && be->hasPawns && PAWN(be)->dtmSwitched) { flip = !flip; bside = !bside; } } else { - flip = pos_stm() != WHITE; + flip = stm() != WHITE; bside = false; } @@ -1325,7 +1325,7 @@ static int probe_ab(Pos *pos, int alpha, int beta, int *success) // Generate (at least) all legal captures including (under)promotions. // It is OK to generate more, as long as they are filtered out below. ExtMove *m = (pos->st-1)->endMoves; - ExtMove *end = !pos_checkers() + ExtMove *end = !checkers() ? add_underprom_caps(pos, m, generate_captures(pos, m)) : generate_evasions(pos, m); pos->st->endMoves = end; @@ -1371,7 +1371,7 @@ int TB_probe_wdl(Pos *pos, int *success) // Generate (at least) all legal captures including (under)promotions. ExtMove *m = (pos->st-1)->endMoves; - ExtMove *end = !pos_checkers() + ExtMove *end = !checkers() ? add_underprom_caps(pos, m, generate_captures(pos, m)) : generate_evasions(pos, m); pos->st->endMoves = end; @@ -1437,7 +1437,7 @@ int TB_probe_wdl(Pos *pos, int *success) if (type_of_m(move) == ENPASSANT) continue; if (is_legal(pos, move)) break; } - if (m == end && !pos_checkers()) { + if (m == end && !checkers()) { end = generate_quiets(pos, end); for (; m < end; m++) { Move move = m->move; @@ -1467,7 +1467,7 @@ static Value probe_dtm_dc(Pos *pos, int won, int *success) ExtMove *end, *m = (pos->st-1)->endMoves; // Generate at least all legal captures including (under)promotions - if (!pos_checkers()) { + if (!checkers()) { end = generate_captures(pos, m); end = add_underprom_caps(pos, m, end); } else @@ -1507,8 +1507,8 @@ static Value probe_dtm_loss(Pos *pos, int *success) // Generate at least all legal captures including (under)promotions ExtMove *end, *m = (pos->st-1)->endMoves; - end = pos_checkers() ? generate_evasions(pos, m) - : add_underprom_caps(pos, m, generate_captures(pos, m)); + end = checkers() ? generate_evasions(pos, m) + : add_underprom_caps(pos, m, generate_captures(pos, m)); pos->st->endMoves = end; for (; m < end; m++) { @@ -1540,8 +1540,8 @@ static Value probe_dtm_win(Pos *pos, int *success) // Generate all moves ExtMove *m = (pos->st-1)->endMoves; - ExtMove *end = pos_checkers() ? generate_evasions(pos, m) - : generate_non_evasions(pos, m); + ExtMove *end = checkers() ? generate_evasions(pos, m) + : generate_non_evasions(pos, m); pos->st->endMoves = end; // Perform a 1-ply search @@ -1586,7 +1586,7 @@ Value TB_probe_dtm2(Pos *pos, int wdl, int *success) ExtMove *end, *m = (pos->st-1)->endMoves; // Generate at least all legal captures including (under)promotions - if (!pos_checkers()) { + if (!checkers()) { end = generate_captures(pos, m); end = add_underprom_caps(pos, m, end); } else @@ -1685,7 +1685,7 @@ int TB_probe_dtz(Pos *pos, int *success) // Generate at least all legal non-capturing pawn moves // including non-capturing promotions. // (The following calls in fact generate all moves.) - end = !pos_checkers() + end = !checkers() ? generate_non_evasions(pos, m) : generate_evasions(pos, m); pos->st->endMoves = end; @@ -1725,7 +1725,7 @@ int TB_probe_dtz(Pos *pos, int *success) // In case of mate, this will cause -1 to be returned. best = WdlToDtz[wdl + 2]; // If wdl < 0, we still have to generate all moves. - if (!pos_checkers()) + if (!checkers()) end = generate_non_evasions(pos, m); else end = generate_evasions(pos, m); @@ -1743,7 +1743,7 @@ int TB_probe_dtz(Pos *pos, int *success) do_move(pos, move, gives_check(pos, pos->st, move)); int v = -TB_probe_dtz(pos, success); if ( v == 1 - && pos_checkers() + && checkers() && generate_legal(pos, (pos->st-1)->endMoves) == (pos->st-1)->endMoves) best = 1; else if (wdl > 0) { @@ -1766,7 +1766,7 @@ int TB_root_probe_dtz(Pos *pos, RootMoves *rm) int v, success; // Obtain 50-move counter for the root position. - int cnt50 = pos_rule50_count(); + int cnt50 = rule50_count(); // Check whether a position was repeated since the last zeroing move. // In that case, we need to be careful and play DTZ-optimal moves if @@ -1784,7 +1784,7 @@ int TB_root_probe_dtz(Pos *pos, RootMoves *rm) do_move(pos, m->pv[0], gives_check(pos, pos->st, m->pv[0])); // Calculate dtz for the current move counting from the root position. - if (pos_rule50_count() == 0) { + if (rule50_count() == 0) { // If the move resets the 50-move counter, dtz is -101/-1/0/1/101. v = -TB_probe_wdl(pos, &success); v = WdlToDtz[v + 2]; @@ -1795,7 +1795,7 @@ int TB_root_probe_dtz(Pos *pos, RootMoves *rm) else if (v < 0) v--; } // Make sure that a mating move gets value 1. - if (pos_checkers() && v == 2) { + if (checkers() && v == 2) { if (generate_legal(pos, (pos->st-1)->endMoves) == (pos->st-1)->endMoves) v = 1; } diff --git a/src/thread.h b/src/thread.h index 1a6efb58..772d0e9a 100644 --- a/src/thread.h +++ b/src/thread.h @@ -85,6 +85,7 @@ struct ThreadPool { #else HANDLE event; #endif + atomic_bool increaseDepth; }; typedef struct ThreadPool ThreadPool;