else if ((p = PieceToChar.find(token)) != string::npos)
{
- put_piece(Piece(p), sq);
+ put_piece(sq, color_of(Piece(p)), type_of(Piece(p)));
sq++;
}
}
else
st->npMaterial[them] -= PieceValue[MG][capture];
- // Remove the captured piece
- byTypeBB[ALL_PIECES] ^= capsq;
- byTypeBB[capture] ^= capsq;
- byColorBB[them] ^= capsq;
-
- // Update piece lists
+ // Update board and piece lists
remove_piece(capsq, them, capture);
// Update material hash key and prefetch access to materialTable
// Move the piece. The tricky Chess960 castle is handled earlier
if (type_of(m) != CASTLE)
- {
- Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to];
- byTypeBB[ALL_PIECES] ^= from_to_bb;
- byTypeBB[pt] ^= from_to_bb;
- byColorBB[us] ^= from_to_bb;
-
- board[from] = NO_PIECE;
- board[to] = pc;
-
move_piece(from, to, us, pt);
- }
// If the moving piece is a pawn do some special extra work
if (pt == PAWN)
assert(relative_rank(us, to) == RANK_8);
assert(promotion >= KNIGHT && promotion <= QUEEN);
- // Replace the pawn with the promoted piece
- byTypeBB[PAWN] ^= to;
- byTypeBB[promotion] |= to;
- board[to] = make_piece(us, promotion);
-
- // Update piece lists and add a new promotion piece to the list
remove_piece(to, us, PAWN);
- add_piece(to, us, promotion);
+ put_piece(to, us, promotion);
// Update hash keys
k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
assert(relative_rank(us, to) == RANK_8);
assert(promotion >= KNIGHT && promotion <= QUEEN);
- // Replace the promoted piece with the pawn
- byTypeBB[promotion] ^= to;
- byTypeBB[PAWN] |= to;
- board[to] = make_piece(us, PAWN);
-
- // Update piece lists and add new pawn to the list
remove_piece(to, us, promotion);
- add_piece(to, us, PAWN);
-
+ put_piece(to, us, PAWN);
pt = PAWN;
}
do_castle(to, from, rto, rfrom);
}
else
- {
- // Put the piece back at the source square
- Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to];
- byTypeBB[ALL_PIECES] ^= from_to_bb;
- byTypeBB[pt] ^= from_to_bb;
- byColorBB[us] ^= from_to_bb;
-
- board[to] = NO_PIECE;
- board[from] = make_piece(us, pt);
-
- move_piece(to, from, us, pt);
- }
+ move_piece(to, from, us, pt); // Put the piece back at the source square
if (capture)
{
assert(piece_on(capsq) == NO_PIECE);
}
- // Restore the captured piece
- byTypeBB[ALL_PIECES] |= capsq;
- byTypeBB[capture] |= capsq;
- byColorBB[them] |= capsq;
-
- board[capsq] = make_piece(them, capture);
-
- // Update piece list, add a new captured piece in capsq square
- add_piece(capsq, them, capture);
+ put_piece(capsq, them, capture); // Restore the captured piece
}
// Finally point our state pointer back to the previous state
void Position::do_castle(Square kfrom, Square kto, Square rfrom, Square rto) {
- Color us = sideToMove;
- Bitboard k_from_to_bb = SquareBB[kfrom] ^ SquareBB[kto];
- Bitboard r_from_to_bb = SquareBB[rfrom] ^ SquareBB[rto];
- byTypeBB[KING] ^= k_from_to_bb;
- byTypeBB[ROOK] ^= r_from_to_bb;
- byTypeBB[ALL_PIECES] ^= k_from_to_bb ^ r_from_to_bb;
- byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb;
-
- // Could be from == to, so first set NO_PIECE then KING and ROOK
- board[kfrom] = board[rfrom] = NO_PIECE;
- board[kto] = make_piece(us, KING);
- board[rto] = make_piece(us, ROOK);
-
- // Could be kfrom == rto, so use a 'tmp' variable
- int tmp = index[kfrom];
- index[rto] = index[rfrom];
- index[kto] = tmp;
- pieceList[us][KING][index[kto]] = kto;
- pieceList[us][ROOK][index[rto]] = rto;
+ // Remove both pieces first since squares could overlap in Chess960
+ remove_piece(kfrom, sideToMove, KING);
+ remove_piece(rfrom, sideToMove, ROOK);
+ board[kfrom] = board[rfrom] = NO_PIECE; // Since remove_piece doesn't do it for us
+ put_piece(kto, sideToMove, KING);
+ put_piece(rto, sideToMove, ROOK);
}
}
-/// Position::put_piece() puts a piece on the given square of the board,
-/// updating the board array, pieces list, bitboards, and piece counts.
-
-void Position::put_piece(Piece p, Square s) {
-
- Color c = color_of(p);
- PieceType pt = type_of(p);
-
- board[s] = p;
- add_piece(s, c, pt);
-
- byTypeBB[ALL_PIECES] |= s;
- byTypeBB[pt] |= s;
- byColorBB[c] |= s;
-}
-
-
/// Position::compute_key() computes the hash key of the position. The hash
/// key is usually updated incrementally as moves are made and unmade, the
/// compute_key() function is only used when a new position is set up, and
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.is_empty(s))
- put_piece(Piece(pos.piece_on(s) ^ 8), ~s);
+ {
+ Piece p = Piece(pos.piece_on(s) ^ 8);
+ put_piece(~s, color_of(p), type_of(p));
+ }
if (pos.can_castle(WHITE_OO))
set_castle_right(BLACK, ~pos.castle_rook_square(WHITE, KING_SIDE));