X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=d1e3f448071a947d7950032cf93eedd9a22d0609;hp=6e6bf38b3dda159a5703386f3d7e1fe192d693ab;hb=5b3fcab1adf9407c97992f8827b2c180d2848308;hpb=3376c68f4bb83dc9fd874eb9d710dab09609ae54 diff --git a/src/position.cpp b/src/position.cpp index 6e6bf38b..d1e3f448 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -315,9 +315,10 @@ void Position::print(Move m) const { /// Position::copy() creates a copy of the input position. -void Position::copy(const Position &pos) { +void Position::copy(const Position& pos) { memcpy(this, &pos, sizeof(Position)); + saveState(); // detach and copy state info } @@ -554,12 +555,12 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { && (direction_between_squares(from, ksq) != direction_between_squares(to, ksq))) return true; - if (move_promotion(m)) // Promotion with check? + if (move_is_promotion(m)) // Promotion with check? { Bitboard b = occupied_squares(); clear_bit(&b, from); - switch (move_promotion(m)) + switch (move_promotion_piece(m)) { case KNIGHT: return bit_is_set(piece_attacks(to), ksq); @@ -720,7 +721,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { if (move_is_castle(m)) do_castle_move(m); - else if (move_promotion(m)) + else if (move_is_promotion(m)) do_promotion_move(m); else if (move_is_ep(m)) do_ep_move(m); @@ -734,7 +735,8 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { assert(color_of_piece_on(from) == us); assert(color_of_piece_on(to) == them || piece_on(to) == EMPTY); - PieceType piece = type_of_piece_on(from); + Piece piece = piece_on(from); + PieceType pt = type_of_piece(piece); st->capture = type_of_piece_on(to); @@ -744,23 +746,21 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { // Move the piece Bitboard move_bb = make_move_bb(from, to); do_move_bb(&(byColorBB[us]), move_bb); - do_move_bb(&(byTypeBB[piece]), move_bb); + do_move_bb(&(byTypeBB[pt]), move_bb); do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares board[to] = board[from]; board[from] = EMPTY; // Update hash key - st->key ^= zobrist[us][piece][from] ^ zobrist[us][piece][to]; + st->key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to]; // Update incremental scores - st->mgValue -= pst(us, piece, from); - st->mgValue += pst(us, piece, to); - st->egValue -= pst(us, piece, from); - st->egValue += pst(us, piece, to); + st->mgValue += pst_delta(piece, from, to); + st->egValue += pst_delta(piece, from, to); // If the moving piece was a king, update the king square - if (piece == KING) + if (pt == KING) kingSquare[us] = to; // Reset en passant square @@ -771,7 +771,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { } // If the moving piece was a pawn do some special extra work - if (piece == PAWN) + if (pt == PAWN) { // Reset rule 50 draw counter st->rule50 = 0; @@ -792,19 +792,22 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { } // Update piece lists - pieceList[us][piece][index[from]] = to; + pieceList[us][pt][index[from]] = to; index[to] = index[from]; - // Update castle rights - st->key ^= zobCastle[st->castleRights]; - st->castleRights &= castleRightsMask[from]; - st->castleRights &= castleRightsMask[to]; - st->key ^= zobCastle[st->castleRights]; + // Update castle rights, try to shortcut a common case + if ((castleRightsMask[from] & castleRightsMask[to]) != ALL_CASTLES) + { + st->key ^= zobCastle[st->castleRights]; + st->castleRights &= castleRightsMask[from]; + st->castleRights &= castleRightsMask[to]; + st->key ^= zobCastle[st->castleRights]; + } // Update checkers bitboard, piece must be already moved st->checkersBB = EmptyBoardBB; Square ksq = king_square(them); - switch (piece) + switch (pt) { case PAWN: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; case KNIGHT: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; @@ -902,26 +905,23 @@ void Position::do_castle_move(Move m) { rto = relative_square(us, SQ_D1); } - // Remove pieces from source squares - clear_bit(&(byColorBB[us]), kfrom); - clear_bit(&(byTypeBB[KING]), kfrom); - clear_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares - clear_bit(&(byColorBB[us]), rfrom); - clear_bit(&(byTypeBB[ROOK]), rfrom); - clear_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares - - // Put pieces on destination squares - set_bit(&(byColorBB[us]), kto); - set_bit(&(byTypeBB[KING]), kto); - set_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares - set_bit(&(byColorBB[us]), rto); - set_bit(&(byTypeBB[ROOK]), rto); - set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares + // Move the pieces + Bitboard kmove_bb = make_move_bb(kfrom, kto); + do_move_bb(&(byColorBB[us]), kmove_bb); + do_move_bb(&(byTypeBB[KING]), kmove_bb); + do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares + + Bitboard rmove_bb = make_move_bb(rfrom, rto); + do_move_bb(&(byColorBB[us]), rmove_bb); + do_move_bb(&(byTypeBB[ROOK]), rmove_bb); + do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares // Update board array + Piece king = piece_of_color_and_type(us, KING); + Piece rook = piece_of_color_and_type(us, ROOK); board[kfrom] = board[rfrom] = EMPTY; - board[kto] = piece_of_color_and_type(us, KING); - board[rto] = piece_of_color_and_type(us, ROOK); + board[kto] = king; + board[rto] = rook; // Update king square kingSquare[us] = kto; @@ -934,14 +934,10 @@ void Position::do_castle_move(Move m) { index[rto] = tmp; // Update incremental scores - st->mgValue -= pst(us, KING, kfrom); - st->mgValue += pst(us, KING, kto); - st->egValue -= pst(us, KING, kfrom); - st->egValue += pst(us, KING, kto); - st->mgValue -= pst(us, ROOK, rfrom); - st->mgValue += pst(us, ROOK, rto); - st->egValue -= pst(us, ROOK, rfrom); - st->egValue += pst(us, ROOK, rto); + st->mgValue += pst_delta(king, kfrom, kto); + st->egValue += pst_delta(king, kfrom, kto); + st->mgValue += pst_delta(rook, rfrom, rto); + st->egValue += pst_delta(rook, rfrom, rto); // Update hash key st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto]; @@ -978,7 +974,7 @@ void Position::do_promotion_move(Move m) { assert(is_ok()); assert(move_is_ok(m)); - assert(move_promotion(m)); + assert(move_is_promotion(m)); us = side_to_move(); them = opposite_color(us); @@ -1001,7 +997,7 @@ void Position::do_promotion_move(Move m) { board[from] = EMPTY; // Insert promoted piece - promotion = move_promotion(m); + promotion = move_promotion_piece(m); assert(promotion >= KNIGHT && promotion <= QUEEN); set_bit(&(byColorBB[us]), to); set_bit(&(byTypeBB[promotion]), to); @@ -1117,12 +1113,11 @@ void Position::do_ep_move(Move m) { st->pawnKey ^= zobrist[them][PAWN][capsq]; // Update incremental scores + Piece pawn = piece_of_color_and_type(us, PAWN); + st->mgValue += pst_delta(pawn, from, to); + st->egValue += pst_delta(pawn, from, to); st->mgValue -= pst(them, PAWN, capsq); - st->mgValue -= pst(us, PAWN, from); - st->mgValue += pst(us, PAWN, to); st->egValue -= pst(them, PAWN, capsq); - st->egValue -= pst(us, PAWN, from); - st->egValue += pst(us, PAWN, to); // Reset en passant square st->epSquare = SQ_NONE; @@ -1148,7 +1143,7 @@ void Position::undo_move(Move m) { if (move_is_castle(m)) undo_castle_move(m); - else if (move_promotion(m)) + else if (move_is_promotion(m)) undo_promotion_move(m); else if (move_is_ep(m)) undo_ep_move(m); @@ -1242,21 +1237,16 @@ void Position::undo_castle_move(Move m) { assert(piece_on(kto) == piece_of_color_and_type(us, KING)); assert(piece_on(rto) == piece_of_color_and_type(us, ROOK)); - // Remove pieces from destination squares - clear_bit(&(byColorBB[us]), kto); - clear_bit(&(byTypeBB[KING]), kto); - clear_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares - clear_bit(&(byColorBB[us]), rto); - clear_bit(&(byTypeBB[ROOK]), rto); - clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares - - // Put pieces on source squares - set_bit(&(byColorBB[us]), kfrom); - set_bit(&(byTypeBB[KING]), kfrom); - set_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares - set_bit(&(byColorBB[us]), rfrom); - set_bit(&(byTypeBB[ROOK]), rfrom); - set_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares + // Put the pieces back at the source square + Bitboard kmove_bb = make_move_bb(kto, kfrom); + do_move_bb(&(byColorBB[us]), kmove_bb); + do_move_bb(&(byTypeBB[KING]), kmove_bb); + do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares + + Bitboard rmove_bb = make_move_bb(rto, rfrom); + do_move_bb(&(byColorBB[us]), rmove_bb); + do_move_bb(&(byTypeBB[ROOK]), rmove_bb); + do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares // Update board board[rto] = board[kto] = EMPTY; @@ -1286,7 +1276,7 @@ void Position::undo_promotion_move(Move m) { PieceType promotion; assert(move_is_ok(m)); - assert(move_promotion(m)); + assert(move_is_promotion(m)); // When we have arrived here, some work has already been done by // Position::undo_move. In particular, the side to move has been switched, @@ -1300,7 +1290,7 @@ void Position::undo_promotion_move(Move m) { assert(piece_on(from) == EMPTY); // Remove promoted piece - promotion = move_promotion(m); + promotion = move_promotion_piece(m); assert(piece_on(to)==piece_of_color_and_type(us, promotion)); assert(promotion >= KNIGHT && promotion <= QUEEN); clear_bit(&(byColorBB[us]), to); @@ -1474,6 +1464,22 @@ int Position::see(Move m) const { return see(move_from(m), move_to(m)); } +int Position::see_sign(Move m) const { + + assert(move_is_ok(m)); + + Square from = move_from(m); + Square to = move_to(m); + + // Early return if SEE cannot be negative because capturing piece value + // is not bigger then captured one. + if ( midgame_value_of_piece_on(from) <= midgame_value_of_piece_on(to) + && type_of_piece_on(from) != KING) + return 1; + + return see(from, to); +} + int Position::see(Square from, Square to) const { // Material values @@ -1593,7 +1599,7 @@ int Position::see(Square from, Square to) const { if (pt == KING && stmAttackers) { assert(n < 32); - swapList[n++] = 100; + swapList[n++] = QueenValueMidgame*10; break; } } while (stmAttackers); @@ -1607,15 +1613,16 @@ int Position::see(Square from, Square to) const { } -/// Position::setStartState() copies the content of the argument +/// Position::saveState() copies the content of the current state /// inside startState and makes st point to it. This is needed /// when the st pointee could become stale, as example because /// the caller is about to going out of scope. -void Position::setStartState(const StateInfo& s) { +void Position::saveState() { - startState = s; + startState = *st; st = &startState; + st->previous = NULL; // as a safe guard } @@ -1966,7 +1973,7 @@ void Position::init_piece_square_tables() { /// the white and black sides reversed. This is only useful for debugging, /// especially for finding evaluation symmetry bugs. -void Position::flipped_copy(const Position &pos) { +void Position::flipped_copy(const Position& pos) { assert(pos.is_ok()); @@ -2091,7 +2098,7 @@ bool Position::is_ok(int* failedStep) const { // Is there more than 2 checkers? if (failedStep) (*failedStep)++; - if (debugCheckerCount && count_1s(st->checkersBB) > 2) + if (debugCheckerCount && count_1s(st->checkersBB) > 2) return false; // Bitboards OK? @@ -2166,7 +2173,7 @@ bool Position::is_ok(int* failedStep) const { if (debugPieceCounts) for (Color c = WHITE; c <= BLACK; c++) for (PieceType pt = PAWN; pt <= KING; pt++) - if (pieceCount[c][pt] != count_1s(pieces_of_color_and_type(c, pt))) + if (pieceCount[c][pt] != count_1s(pieces_of_color_and_type(c, pt))) return false; if (failedStep) (*failedStep)++;