Score Position::PieceSquareTable[16][64];
// Material values arrays, indexed by Piece
-const Value Position::PieceValueMidgame[17] = {
+const Value PieceValueMidgame[17] = {
VALUE_ZERO,
PawnValueMidgame, KnightValueMidgame, BishopValueMidgame,
RookValueMidgame, QueenValueMidgame, VALUE_ZERO,
RookValueMidgame, QueenValueMidgame
};
-const Value Position::PieceValueEndgame[17] = {
+const Value PieceValueEndgame[17] = {
VALUE_ZERO,
PawnValueEndgame, KnightValueEndgame, BishopValueEndgame,
RookValueEndgame, QueenValueEndgame, VALUE_ZERO,
RookValueEndgame, QueenValueEndgame
};
-// Material values array used by SEE, indexed by PieceType
-const Value Position::seeValues[] = {
- VALUE_ZERO,
- PawnValueMidgame, KnightValueMidgame, BishopValueMidgame,
- RookValueMidgame, QueenValueMidgame, QueenValueMidgame*10
-};
-
namespace {
Color us = pos.side_to_move();
Color them = opposite_color(us);
+ Square ksq = pos.king_square(them);
- ksq = pos.king_square(them);
dcCandidates = pos.discovered_check_candidates(us);
pinned = pos.pinned_pieces(us);
if (move)
{
Position p(*this, thread());
- string dd = (color_of_piece_on(move_from(move)) == BLACK ? ".." : "");
+ string dd = (piece_color(piece_on(move_from(move))) == BLACK ? ".." : "");
cout << "\nMove is: " << dd << move_to_san(p, move);
}
if (piece == PIECE_NONE && square_color(sq) == DARK)
piece = PIECE_NONE_DARK_SQ;
- char c = (color_of_piece_on(sq) == BLACK ? '=' : ' ');
+ char c = (piece_color(piece_on(sq)) == BLACK ? '=' : ' ');
cout << c << PieceToChar[piece] << c << '|';
}
}
do_move_bb(&occ, make_move_bb(f, t));
xray = ( (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN))
|(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN)))
- & pieces_of_color(color_of_piece_on(f));
+ & pieces_of_color(piece_color(piece_on(f)));
// If we have attacks we need to verify that are caused by our move
// and are not already existent ones.
Color us = side_to_move();
Square from = move_from(m);
- assert(color_of_piece_on(from) == us);
+ assert(piece_color(piece_on(from)) == us);
assert(piece_on(king_square(us)) == make_piece(us, KING));
// En passant captures are a tricky special case. Because they are
// If the moving piece is a king, check whether the destination
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
- if (type_of_piece_on(from) == KING)
+ if (piece_type(piece_on(from)) == KING)
return move_is_castle(m) || !(attackers_to(move_to(m)) & pieces_of_color(opposite_color(us)));
// A non-king move is legal if and only if it is not pinned or it
// If the from square is not occupied by a piece belonging to the side to
// move, the move is obviously not legal.
- if (pc == PIECE_NONE || color_of_piece(pc) != us)
+ if (pc == PIECE_NONE || piece_color(pc) != us)
return false;
// The destination square cannot be occupied by a friendly piece
- if (color_of_piece_on(to) == us)
+ if (piece_color(piece_on(to)) == us)
return false;
// Handle the special case of a pawn move
- if (type_of_piece(pc) == PAWN)
+ if (piece_type(pc) == PAWN)
{
// Move direction must be compatible with pawn color
int direction = to - from;
case DELTA_SE:
// Capture. The destination square must be occupied by an enemy
// piece (en passant captures was handled earlier).
- if (color_of_piece_on(to) != them)
+ if (piece_color(piece_on(to)) != them)
return false;
// From and to files must be one file apart, avoids a7h5
{
// In case of king moves under check we have to remove king so to catch
// as invalid moves like b1a1 when opposite queen is on c1.
- if (type_of_piece_on(from) == KING)
+ if (piece_type(piece_on(from)) == KING)
{
Bitboard b = occupied_squares();
clear_bit(&b, from);
assert(is_ok());
assert(move_is_ok(m));
assert(ci.dcCandidates == discovered_check_candidates(side_to_move()));
- assert(color_of_piece_on(move_from(m)) == side_to_move());
- assert(piece_on(ci.ksq) == make_piece(opposite_color(side_to_move()), KING));
+ assert(piece_color(piece_on(move_from(m))) == side_to_move());
Square from = move_from(m);
Square to = move_to(m);
- PieceType pt = type_of_piece_on(from);
+ PieceType pt = piece_type(piece_on(from));
// Direct check ?
if (bit_is_set(ci.checkSq[pt], to))
{
// For pawn and king moves we need to verify also direction
if ( (pt != PAWN && pt != KING)
- || !squares_aligned(from, to, ci.ksq))
+ || !squares_aligned(from, to, king_square(opposite_color(side_to_move()))))
return true;
}
Color us = side_to_move();
Bitboard b = occupied_squares();
+ Square ksq = king_square(opposite_color(us));
// Promotion with check ?
if (move_is_promotion(m))
switch (promotion_piece_type(m))
{
case KNIGHT:
- return bit_is_set(attacks_from<KNIGHT>(to), ci.ksq);
+ return bit_is_set(attacks_from<KNIGHT>(to), ksq);
case BISHOP:
- return bit_is_set(bishop_attacks_bb(to, b), ci.ksq);
+ return bit_is_set(bishop_attacks_bb(to, b), ksq);
case ROOK:
- return bit_is_set(rook_attacks_bb(to, b), ci.ksq);
+ return bit_is_set(rook_attacks_bb(to, b), ksq);
case QUEEN:
- return bit_is_set(queen_attacks_bb(to, b), ci.ksq);
+ return bit_is_set(queen_attacks_bb(to, b), ksq);
default:
assert(false);
}
clear_bit(&b, from);
clear_bit(&b, capsq);
set_bit(&b, to);
- return (rook_attacks_bb(ci.ksq, b) & pieces(ROOK, QUEEN, us))
- ||(bishop_attacks_bb(ci.ksq, b) & pieces(BISHOP, QUEEN, us));
+ return (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us))
+ ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us));
}
// Castling with check ?
clear_bit(&b, rfrom);
set_bit(&b, rto);
set_bit(&b, kto);
- return bit_is_set(rook_attacks_bb(rto, b), ci.ksq);
+ return bit_is_set(rook_attacks_bb(rto, b), ksq);
}
return false;
bool pm = move_is_promotion(m);
Piece piece = piece_on(from);
- PieceType pt = type_of_piece(piece);
- PieceType capture = ep ? PAWN : type_of_piece_on(to);
+ PieceType pt = piece_type(piece);
+ PieceType capture = ep ? PAWN : piece_type(piece_on(to));
- assert(color_of_piece_on(from) == us);
- assert(color_of_piece_on(to) == them || square_is_empty(to));
+ assert(piece_color(piece_on(from)) == us);
+ assert(piece_color(piece_on(to)) == them || square_is_empty(to));
assert(!(ep || pm) || piece == make_piece(us, PAWN));
assert(!pm || relative_rank(us, to) == RANK_8);
if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from))
{
if (pt != ROOK)
- st->checkersBB |= (attacks_from<ROOK>(ci.ksq) & pieces(ROOK, QUEEN, us));
+ st->checkersBB |= (attacks_from<ROOK>(king_square(them)) & pieces(ROOK, QUEEN, us));
if (pt != BISHOP)
- st->checkersBB |= (attacks_from<BISHOP>(ci.ksq) & pieces(BISHOP, QUEEN, us));
+ st->checkersBB |= (attacks_from<BISHOP>(king_square(them)) & pieces(BISHOP, QUEEN, us));
}
}
}
bool ep = move_is_ep(m);
bool pm = move_is_promotion(m);
- PieceType pt = type_of_piece_on(to);
+ PieceType pt = piece_type(piece_on(to));
assert(square_is_empty(from));
- assert(color_of_piece_on(to) == us);
+ assert(piece_color(piece_on(to)) == us);
assert(!pm || relative_rank(us, to) == RANK_8);
assert(!ep || to == st->previous->epSquare);
assert(!ep || relative_rank(us, to) == RANK_6);
// Early return if SEE cannot be negative because captured piece value
// is not less then capturing one. Note that king moves always return
// here because king midgame value is set to 0.
- if (midgame_value_of_piece_on(to) >= midgame_value_of_piece_on(from))
+ if (piece_value_midgame(piece_on(to)) >= piece_value_midgame(piece_on(from)))
return 1;
return see(m);
from = move_from(m);
to = move_to(m);
- capturedType = type_of_piece_on(to);
+ capturedType = piece_type(piece_on(to));
occupied = occupied_squares();
// Handle en passant moves
- if (st->epSquare == to && type_of_piece_on(from) == PAWN)
+ if (st->epSquare == to && piece_type(piece_on(from)) == PAWN)
{
Square capQq = (side_to_move() == WHITE ? to - DELTA_N : to - DELTA_S);
assert(capturedType == PIECE_TYPE_NONE);
- assert(type_of_piece_on(capQq) == PAWN);
+ assert(piece_type(piece_on(capQq)) == PAWN);
// Remove the captured pawn
clear_bit(&occupied, capQq);
attackers = attackers_to(to, occupied);
// If the opponent has no attackers we are finished
- stm = opposite_color(color_of_piece_on(from));
+ stm = opposite_color(piece_color(piece_on(from)));
stmAttackers = attackers & pieces_of_color(stm);
if (!stmAttackers)
- return seeValues[capturedType];
+ return PieceValueMidgame[capturedType];
// The destination square is defended, which makes things rather more
// difficult to compute. We proceed by building up a "swap list" containing
// destination square, where the sides alternately capture, and always
// capture with the least valuable piece. After each capture, we look for
// new X-ray attacks from behind the capturing piece.
- swapList[0] = seeValues[capturedType];
- capturedType = type_of_piece_on(from);
+ swapList[0] = PieceValueMidgame[capturedType];
+ capturedType = piece_type(piece_on(from));
do {
// Locate the least valuable attacker for the side to move. The loop
// Add the new entry to the swap list
assert(slIndex < 32);
- swapList[slIndex] = -swapList[slIndex - 1] + seeValues[capturedType];
+ swapList[slIndex] = -swapList[slIndex - 1] + PieceValueMidgame[capturedType];
slIndex++;
// Remember the value of the capturing piece, and change the side to
void Position::put_piece(Piece p, Square s) {
- Color c = color_of_piece(p);
- PieceType pt = type_of_piece(p);
+ Color c = piece_color(p);
+ PieceType pt = piece_type(p);
board[s] = p;
index[s] = pieceCount[c][pt]++;
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (square_is_occupied(s))
- result ^= zobrist[color_of_piece_on(s)][type_of_piece_on(s)][s];
+ result ^= zobrist[piece_color(piece_on(s))][piece_type(piece_on(s))][s];
if (ep_square() != SQ_NONE)
result ^= zobEp[ep_square()];
{
int kingCount[2] = {0, 0};
for (Square s = SQ_A1; s <= SQ_H8; s++)
- if (type_of_piece_on(s) == KING)
- kingCount[color_of_piece_on(s)]++;
+ if (piece_type(piece_on(s)) == KING)
+ kingCount[piece_color(piece_on(s))]++;
if (kingCount[0] != 1 || kingCount[1] != 1)
return false;
if (can_castle_queenside(c) && piece_on(initial_qr_square(c)) != make_piece(c, ROOK))
return false;
}
- if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
- return false;
- if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
- return false;
- if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
- return false;
- if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
- return false;
+ // If we cannot castle castleRightsMask[] could be not valid, for instance when
+ // king initial file is FILE_A as queen rook.
+ if (can_castle(WHITE) || can_castle(BLACK))
+ {
+ if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
+ return false;
+ if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
+ return false;
+ if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
+ return false;
+ if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
+ return false;
+ }
}
if (failedStep) *failedStep = 0;