#include "position.h"
#include "psqtab.h"
#include "san.h"
+#include "tt.h"
#include "ucioption.h"
using std::string;
// case of non-reversible moves is taken care of later.
st->rule50++;
+ // Update side to move
+ st->key ^= zobSideToMove;
+
if (move_is_castle(m))
do_castle_move(m);
else if (move_is_promotion(m))
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);
if (st->capture)
- do_capture_move(st->capture, them, to);
-
- // 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[0]), move_bb); // HACK: byTypeBB[0] == occupied squares
-
- board[to] = board[from];
- board[from] = EMPTY;
+ do_capture_move(st->capture, them, to);
// Update hash key
- st->key ^= zobrist[us][piece][from] ^ zobrist[us][piece][to];
-
- // Update incremental scores
- st->mgValue -= pst<MidGame>(us, piece, from);
- st->mgValue += pst<MidGame>(us, piece, to);
- st->egValue -= pst<EndGame>(us, piece, from);
- st->egValue += pst<EndGame>(us, piece, to);
-
- // If the moving piece was a king, update the king square
- if (piece == KING)
- kingSquare[us] = to;
+ st->key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
// Reset en passant square
if (st->epSquare != SQ_NONE)
st->epSquare = SQ_NONE;
}
+ // 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];
+ }
+
+ // Prefetch TT access as soon as we know key is updated
+ TT.prefetch(st->key);
+
+ // Move the piece
+ Bitboard move_bb = make_move_bb(from, to);
+ do_move_bb(&(byColorBB[us]), 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;
+
// 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;
}
}
+ // Update incremental scores
+ st->mgValue += pst_delta<MidGame>(piece, from, to);
+ st->egValue += pst_delta<EndGame>(piece, from, to);
+
+ // If the moving piece was a king, update the king square
+ if (pt == KING)
+ kingSquare[us] = to;
+
// Update piece lists
- pieceList[us][piece][index[from]] = to;
+ pieceList[us][pt][index[from]] = to;
index[to] = index[from];
- // 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<PAWN>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
case KNIGHT: update_checkers<KNIGHT>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
}
// Finish
- st->key ^= zobSideToMove;
sideToMove = opposite_color(sideToMove);
gamePly++;
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;
index[rto] = tmp;
// Update incremental scores
- st->mgValue -= pst<MidGame>(us, KING, kfrom);
- st->mgValue += pst<MidGame>(us, KING, kto);
- st->egValue -= pst<EndGame>(us, KING, kfrom);
- st->egValue += pst<EndGame>(us, KING, kto);
- st->mgValue -= pst<MidGame>(us, ROOK, rfrom);
- st->mgValue += pst<MidGame>(us, ROOK, rto);
- st->egValue -= pst<EndGame>(us, ROOK, rfrom);
- st->egValue += pst<EndGame>(us, ROOK, rto);
+ st->mgValue += pst_delta<MidGame>(king, kfrom, kto);
+ st->egValue += pst_delta<EndGame>(king, kfrom, kto);
+ st->mgValue += pst_delta<MidGame>(rook, rfrom, rto);
+ st->egValue += pst_delta<EndGame>(rook, rfrom, rto);
// Update hash key
st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
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);
st->pawnKey ^= zobrist[them][PAWN][capsq];
// Update incremental scores
+ Piece pawn = piece_of_color_and_type(us, PAWN);
+ st->mgValue += pst_delta<MidGame>(pawn, from, to);
+ st->egValue += pst_delta<EndGame>(pawn, from, to);
st->mgValue -= pst<MidGame>(them, PAWN, capsq);
- st->mgValue -= pst<MidGame>(us, PAWN, from);
- st->mgValue += pst<MidGame>(us, PAWN, to);
st->egValue -= pst<EndGame>(them, PAWN, capsq);
- st->egValue -= pst<EndGame>(us, PAWN, from);
- st->egValue += pst<EndGame>(us, PAWN, to);
// Reset en passant square
st->epSquare = SQ_NONE;
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;
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,
history[gamePly] = st->key;
// Update the necessary information
- sideToMove = opposite_color(sideToMove);
if (st->epSquare != SQ_NONE)
st->key ^= zobEp[st->epSquare];
+ st->key ^= zobSideToMove;
+ TT.prefetch(st->key);
+ sideToMove = opposite_color(sideToMove);
st->epSquare = SQ_NONE;
st->rule50++;
gamePly++;
- st->key ^= zobSideToMove;
st->mgValue += (sideToMove == WHITE)? TempoValueMidgame : -TempoValueMidgame;
st->egValue += (sideToMove == WHITE)? TempoValueEndgame : -TempoValueEndgame;
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