X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fposition.cpp;h=1fe723aec461e20a303582484349b9696ca9c552;hb=70b7404a63b74a57d4e1d0b9192b00837e9a1af8;hp=e30629186fdb65ec9321c1fbb72c064cba268814;hpb=d892063cd34f0e1ca9f36f0514ebe87767120356;p=stockfish diff --git a/src/position.cpp b/src/position.cpp index e3062918..1fe723ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -703,7 +703,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { // pointer to point to the new, ready to be updated, state. struct ReducedStateInfo { Key key, pawnKey, materialKey; - int castleRights, rule50; + int castleRights, rule50, pliesFromNull; Square epSquare; Value mgValue, egValue; Value npMaterial[2]; @@ -724,6 +724,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { // Increment the 50 moves rule draw counter. Resetting it to zero in the // case of non-reversible moves is taken care of later. st->rule50++; + st->pliesFromNull++; if (move_is_castle(m)) { @@ -1238,11 +1239,11 @@ void Position::do_null_move(StateInfo& backupSt) { // Note that differently from normal case here backupSt is actually used as // a backup storage not as a new state to be used. backupSt.key = st->key; - backupSt.rule50 = st->rule50; backupSt.epSquare = st->epSquare; backupSt.mgValue = st->mgValue; backupSt.egValue = st->egValue; backupSt.previous = st->previous; + backupSt.pliesFromNull = st->pliesFromNull; st->previous = &backupSt; // Save the current key to the history[] array, in order to be able to @@ -1258,7 +1259,8 @@ void Position::do_null_move(StateInfo& backupSt) { sideToMove = opposite_color(sideToMove); st->epSquare = SQ_NONE; - st->rule50 = 0; + st->rule50++; + st->pliesFromNull = 0; gamePly++; st->mgValue += (sideToMove == WHITE)? TempoValueMidgame : -TempoValueMidgame; @@ -1276,14 +1278,15 @@ void Position::undo_null_move() { // Restore information from the our backup StateInfo object StateInfo* backupSt = st->previous; st->key = backupSt->key; - st->rule50 = backupSt->rule50; st->epSquare = backupSt->epSquare; st->mgValue = backupSt->mgValue; st->egValue = backupSt->egValue; st->previous = backupSt->previous; + st->pliesFromNull = backupSt->pliesFromNull; // Update the necessary information sideToMove = opposite_color(sideToMove); + st->rule50--; gamePly--; } @@ -1297,13 +1300,13 @@ void Position::undo_null_move() { int Position::see(Square to) const { assert(square_is_ok(to)); - return see(SQ_NONE, to); + return see(SQ_NONE, to, false); } int Position::see(Move m) const { assert(move_is_ok(m)); - return see(move_from(m), move_to(m)); + return see(move_from(m), move_to(m), false); } int Position::see_sign(Move m) const { @@ -1319,10 +1322,10 @@ int Position::see_sign(Move m) const { && type_of_piece_on(from) != KING) return 1; - return see(from, to); + return see(from, to, true); } -int Position::see(Square from, Square to) const { +int Position::see(Square from, Square to, bool shortcut) const { // Material values static const int seeValues[18] = { @@ -1334,7 +1337,9 @@ int Position::see(Square from, Square to) const { }; Bitboard attackers, stmAttackers, b; + int pieceDiff = 0; + assert(!shortcut || from != SQ_NONE); assert(square_is_ok(from) || from == SQ_NONE); assert(square_is_ok(to)); @@ -1347,6 +1352,26 @@ int Position::see(Square from, Square to) const { Piece capture = piece_on(to); Bitboard occ = occupied_squares(); + // King cannot be recaptured + if (type_of_piece(piece) == KING) + return seeValues[capture]; + + // If captured piece is defended by enemy pawns or knights then SEE is negative + // when captured piece value does not compensate the lost of capturing one. + if (shortcut) + { + pieceDiff = seeValues[piece] - seeValues[capture]; + + if ( pieceDiff > seeValues[PAWN] + &&(attacks_from(to, us) & pieces(PAWN, them))) + return -(pieceDiff - seeValues[PAWN] / 2); + + if ( pieceDiff > seeValues[KNIGHT] + && pieces(KNIGHT, them) + &&(pieces(KNIGHT, them) & attacks_from(to))) + return -(pieceDiff - seeValues[KNIGHT] / 2); + } + // Handle en passant moves if (st->epSquare == to && type_of_piece_on(from) == PAWN) { @@ -1417,6 +1442,15 @@ int Position::see(Square from, Square to) const { for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++) assert(pt < KING); + // If captured piece is defended by an enemy piece then SEE is negative + // if captured piece value does not compensate the lost of capturing one. + if (pieceDiff > seeValues[pt]) + { + assert(shortcut); + return -(pieceDiff - seeValues[pt] / 2); + } else + pieceDiff = 0; // Only first cycle + // Remove the attacker we just found from the 'attackers' bitboard, // and scan for new X-ray attacks behind the attacker. b = stmAttackers & pieces(pt); @@ -1485,8 +1519,8 @@ void Position::clear() { for (int i = 0; i < 64; i++) board[i] = EMPTY; - for (int i = 0; i < 7; i++) - for (int j = 0; j < 8; j++) + for (int i = 0; i < 8; i++) + for (int j = 0; j < 16; j++) pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE; sideToMove = WHITE; @@ -1684,7 +1718,7 @@ bool Position::is_draw() const { return true; // Draw by repetition? - for (int i = 2; i < Min(gamePly, st->rule50); i += 2) + for (int i = 2; i < Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2) if (history[gamePly - i] == st->key) return true;