X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=64b833857b9976080db3b587715e8319f5da8e39;hp=4d132e033244e602fd0f1edfeedfe3244a7759fe;hb=3a4d6e2034a872d9c8550a5024bacb3bd27dcad3;hpb=595c7d75a2d8c6bc6beade1aa0c50fcf79083661 diff --git a/src/position.cpp b/src/position.cpp index 4d132e03..64b83385 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -27,6 +27,7 @@ #include #include +#include "bitcount.h" #include "mersenne.h" #include "movegen.h" #include "movepick.h" @@ -314,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 } @@ -553,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); @@ -719,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); @@ -741,12 +743,11 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { do_capture_move(st->capture, them, to); // Move the piece - clear_bit(&(byColorBB[us]), from); - clear_bit(&(byTypeBB[piece]), from); - clear_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares - set_bit(&(byColorBB[us]), to); - set_bit(&(byTypeBB[piece]), to); - set_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares + 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[0]), move_bb); // HACK: byTypeBB[0] == occupied squares + board[to] = board[from]; board[from] = EMPTY; @@ -795,11 +796,14 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { pieceList[us][piece][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; @@ -838,6 +842,7 @@ void Position::do_capture_move(PieceType capture, Color them, Square to) { // Remove captured piece clear_bit(&(byColorBB[them]), to); clear_bit(&(byTypeBB[capture]), to); + clear_bit(&(byTypeBB[0]), to); // Update hash key st->key ^= zobrist[them][capture][to]; @@ -1000,7 +1005,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); @@ -1080,21 +1085,17 @@ void Position::do_ep_move(Move m) { assert(piece_on(from) == piece_of_color_and_type(us, PAWN)); assert(piece_on(capsq) == piece_of_color_and_type(them, PAWN)); - // Remove captured piece + // Remove captured pawn clear_bit(&(byColorBB[them]), capsq); clear_bit(&(byTypeBB[PAWN]), capsq); clear_bit(&(byTypeBB[0]), capsq); // HACK: byTypeBB[0] == occupied squares board[capsq] = EMPTY; - // Remove moving piece from source square - clear_bit(&(byColorBB[us]), from); - clear_bit(&(byTypeBB[PAWN]), from); - clear_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares - - // Put moving piece on destination square - set_bit(&(byColorBB[us]), to); - set_bit(&(byTypeBB[PAWN]), to); - set_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares + // Move capturing pawn + Bitboard move_bb = make_move_bb(from, to); + do_move_bb(&(byColorBB[us]), move_bb); + do_move_bb(&(byTypeBB[PAWN]), move_bb); + do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares board[to] = board[from]; board[from] = EMPTY; @@ -1151,7 +1152,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); @@ -1170,17 +1171,13 @@ void Position::undo_move(Move m) { assert(color_of_piece_on(to) == us); // Put the piece back at the source square + Bitboard move_bb = make_move_bb(to, from); piece = type_of_piece_on(to); - set_bit(&(byColorBB[us]), from); - set_bit(&(byTypeBB[piece]), from); - set_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares + do_move_bb(&(byColorBB[us]), move_bb); + do_move_bb(&(byTypeBB[piece]), move_bb); + do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares board[from] = piece_of_color_and_type(us, piece); - // Clear the destination square - clear_bit(&(byColorBB[us]), to); - clear_bit(&(byTypeBB[piece]), to); - clear_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares - // If the moving piece was a king, update the king square if (piece == KING) kingSquare[us] = from; @@ -1193,7 +1190,7 @@ void Position::undo_move(Move m) { { assert(st->capture != KING); - // Replace the captured piece + // Restore the captured piece set_bit(&(byColorBB[them]), to); set_bit(&(byTypeBB[st->capture]), to); set_bit(&(byTypeBB[0]), to); @@ -1307,7 +1304,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); @@ -1375,22 +1372,18 @@ void Position::undo_ep_move(Move m) { assert(piece_on(from) == EMPTY); assert(piece_on(capsq) == EMPTY); - // Replace captured piece + // Restore captured pawn set_bit(&(byColorBB[them]), capsq); set_bit(&(byTypeBB[PAWN]), capsq); set_bit(&(byTypeBB[0]), capsq); board[capsq] = piece_of_color_and_type(them, PAWN); - // Remove moving piece from destination square - clear_bit(&(byColorBB[us]), to); - clear_bit(&(byTypeBB[PAWN]), to); - clear_bit(&(byTypeBB[0]), to); + // Move capturing pawn back to source square + Bitboard move_bb = make_move_bb(to, from); + do_move_bb(&(byColorBB[us]), move_bb); + do_move_bb(&(byTypeBB[PAWN]), move_bb); + do_move_bb(&(byTypeBB[0]), move_bb); board[to] = EMPTY; - - // Replace moving piece at source square - set_bit(&(byColorBB[us]), from); - set_bit(&(byTypeBB[PAWN]), from); - set_bit(&(byTypeBB[0]), from); board[from] = piece_of_color_and_type(us, PAWN); // Update piece list @@ -1604,7 +1597,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); @@ -1618,15 +1611,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 } @@ -1977,7 +1971,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());