More natural and nicer. Idea from Critter.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
- wksq = flip(pos.king_square(BLACK));
- bksq = flip(pos.king_square(WHITE));
- wpsq = flip(pos.piece_list(BLACK, PAWN)[0]);
- stm = flip(pos.side_to_move());
+ wksq = ~pos.king_square(BLACK);
+ bksq = ~pos.king_square(WHITE);
+ wpsq = ~pos.piece_list(BLACK, PAWN)[0];
+ stm = ~pos.side_to_move();
}
if (file_of(wpsq) >= FILE_E)
}
if (file_of(wpsq) >= FILE_E)
if (strongerSide == BLACK)
{
if (strongerSide == BLACK)
{
- wksq = flip(wksq);
- wrsq = flip(wrsq);
- bksq = flip(bksq);
- bpsq = flip(bpsq);
+ wksq = ~wksq;
+ wrsq = ~wrsq;
+ bksq = ~bksq;
+ bpsq = ~bpsq;
}
Square queeningSq = make_square(file_of(bpsq), RANK_1);
}
Square queeningSq = make_square(file_of(bpsq), RANK_1);
// pawn is on the left half of the board.
if (strongerSide == BLACK)
{
// pawn is on the left half of the board.
if (strongerSide == BLACK)
{
- wksq = flip(wksq);
- wrsq = flip(wrsq);
- wpsq = flip(wpsq);
- bksq = flip(bksq);
- brsq = flip(brsq);
+ wksq = ~wksq;
+ wrsq = ~wrsq;
+ wpsq = ~wpsq;
+ bksq = ~bksq;
+ brsq = ~brsq;
}
if (file_of(wpsq) > FILE_D)
{
}
if (file_of(wpsq) > FILE_D)
{
if (strongerSide == BLACK)
{
if (strongerSide == BLACK)
{
- wksq = flip(wksq);
- bksq = flip(bksq);
- wpsq = flip(wpsq);
- stm = flip(stm);
+ wksq = ~wksq;
+ bksq = ~bksq;
+ wpsq = ~wpsq;
+ stm = ~stm;
}
if (file_of(wpsq) >= FILE_E)
}
if (file_of(wpsq) >= FILE_E)
template<EndgameType E, typename T = typename eg_family<E>::type>
struct Endgame : public EndgameBase<T> {
template<EndgameType E, typename T = typename eg_family<E>::type>
struct Endgame : public EndgameBase<T> {
- explicit Endgame(Color c) : strongerSide(c), weakerSide(flip(c)) {}
+ explicit Endgame(Color c) : strongerSide(c), weakerSide(~c) {}
Color color() const { return strongerSide; }
T operator()(const Position&) const;
Color color() const { return strongerSide; }
T operator()(const Position&) const;
for (c = WHITE; c <= BLACK; c++)
{
// Skip if other side has non-pawn pieces
for (c = WHITE; c <= BLACK; c++)
{
// Skip if other side has non-pawn pieces
- if (pos.non_pawn_material(flip(c)))
+ if (pos.non_pawn_material(~c))
continue;
b = ei.pi->passed_pawns(c);
continue;
b = ei.pi->passed_pawns(c);
// Compute plies to queening and check direct advancement
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
// Compute plies to queening and check direct advancement
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
- oppMovesToGo = square_distance(pos.king_square(flip(c)), queeningSquare) - int(c != pos.side_to_move());
+ oppMovesToGo = square_distance(pos.king_square(~c), queeningSquare) - int(c != pos.side_to_move());
pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);
if (movesToGo >= oppMovesToGo && !pathDefended)
pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);
if (movesToGo >= oppMovesToGo && !pathDefended)
return SCORE_ZERO;
winnerSide = (pliesToQueen[WHITE] < pliesToQueen[BLACK] ? WHITE : BLACK);
return SCORE_ZERO;
winnerSide = (pliesToQueen[WHITE] < pliesToQueen[BLACK] ? WHITE : BLACK);
- loserSide = flip(winnerSide);
+ loserSide = ~winnerSide;
// Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
b = candidates = pos.pieces(PAWN, loserSide);
// Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
b = candidates = pos.pieces(PAWN, loserSide);
Square rfrom = pos.castle_rook_square(CR[us]);
Square kto = relative_square(us, Side == KING_SIDE ? SQ_G1 : SQ_C1);
Square rto = relative_square(us, Side == KING_SIDE ? SQ_F1 : SQ_D1);
Square rfrom = pos.castle_rook_square(CR[us]);
Square kto = relative_square(us, Side == KING_SIDE ? SQ_G1 : SQ_C1);
Square rto = relative_square(us, Side == KING_SIDE ? SQ_F1 : SQ_D1);
- Bitboard enemies = pos.pieces(flip(us));
+ Bitboard enemies = pos.pieces(~us);
assert(!pos.in_check());
assert(pos.piece_on(kfrom) == make_piece(us, KING));
assert(!pos.in_check());
assert(pos.piece_on(kfrom) == make_piece(us, KING));
Bitboard target;
if (Type == MV_CAPTURE)
Bitboard target;
if (Type == MV_CAPTURE)
- target = pos.pieces(flip(us));
+ target = pos.pieces(~us);
else if (Type == MV_NON_CAPTURE)
target = pos.empty_squares();
else if (Type == MV_NON_EVASION)
else if (Type == MV_NON_CAPTURE)
target = pos.empty_squares();
else if (Type == MV_NON_EVASION)
- target = pos.pieces(flip(us)) | pos.empty_squares();
+ target = pos.pieces(~us) | pos.empty_squares();
mlist = generate_piece_moves<PAWN, Type>(pos, mlist, us, target);
mlist = generate_piece_moves<KNIGHT>(pos, mlist, us, target);
mlist = generate_piece_moves<PAWN, Type>(pos, mlist, us, target);
mlist = generate_piece_moves<KNIGHT>(pos, mlist, us, target);
checkersCnt++;
checksq = pop_1st_bit(&b);
checkersCnt++;
checksq = pop_1st_bit(&b);
- assert(color_of(pos.piece_on(checksq)) == flip(us));
+ assert(color_of(pos.piece_on(checksq)) == ~us);
switch (type_of(pos.piece_on(checksq)))
{
switch (type_of(pos.piece_on(checksq)))
{
CheckInfo::CheckInfo(const Position& pos) {
CheckInfo::CheckInfo(const Position& pos) {
- Color them = flip(pos.side_to_move());
+ Color them = ~pos.side_to_move();
ksq = pos.king_square(them);
pinned = pos.pinned_pieces();
ksq = pos.king_square(them);
pinned = pos.pinned_pieces();
st->value = compute_value();
st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
st->value = compute_value();
st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
- st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(flip(sideToMove));
+ st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
chess960 = isChess960;
assert(pos_is_ok());
chess960 = isChess960;
assert(pos_is_ok());
// Pinned pieces protect our king, dicovery checks attack the enemy king
Bitboard b, result = 0;
// Pinned pieces protect our king, dicovery checks attack the enemy king
Bitboard b, result = 0;
- Bitboard pinners = pieces(FindPinned ? flip(sideToMove) : sideToMove);
- Square ksq = king_square(FindPinned ? sideToMove : flip(sideToMove));
+ Bitboard pinners = pieces(FindPinned ? ~sideToMove : sideToMove);
+ Square ksq = king_square(FindPinned ? sideToMove : ~sideToMove);
// Pinners are sliders, that give check when candidate pinned is removed
pinners &= (pieces(ROOK, QUEEN) & PseudoAttacks[ROOK][ksq])
// Pinners are sliders, that give check when candidate pinned is removed
pinners &= (pieces(ROOK, QUEEN) & PseudoAttacks[ROOK][ksq])
assert(is_ok(m));
assert(pinned == pinned_pieces());
assert(is_ok(m));
assert(pinned == pinned_pieces());
- Color us = side_to_move();
Square from = from_sq(m);
assert(color_of(piece_on(from)) == us);
Square from = from_sq(m);
assert(color_of(piece_on(from)) == us);
// the move is made.
if (is_enpassant(m))
{
// the move is made.
if (is_enpassant(m))
{
Square to = to_sq(m);
Square capsq = to + pawn_push(them);
Square ksq = king_square(us);
Square to = to_sq(m);
Square capsq = to + pawn_push(them);
Square ksq = king_square(us);
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
if (type_of(piece_on(from)) == KING)
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
if (type_of(piece_on(from)) == KING)
- return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(flip(us)));
+ return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(~us));
// A non-king move is legal if and only if it is not pinned or it
// is moving along the ray towards or away from the king.
// A non-king move is legal if and only if it is not pinned or it
// is moving along the ray towards or away from the king.
bool Position::is_pseudo_legal(const Move m) const {
Color us = sideToMove;
bool Position::is_pseudo_legal(const Move m) const {
Color us = sideToMove;
- Color them = flip(sideToMove);
+ Color them = ~sideToMove;
Square from = from_sq(m);
Square to = to_sq(m);
Piece pc = piece_on(from);
Square from = from_sq(m);
Square to = to_sq(m);
Piece pc = piece_on(from);
{
Bitboard b = occupied_squares();
clear_bit(&b, from);
{
Bitboard b = occupied_squares();
clear_bit(&b, from);
- if (attackers_to(to_sq(m), b) & pieces(flip(us)))
+ if (attackers_to(to_sq(m), b) & pieces(~us))
assert(is_ok(m));
assert(ci.dcCandidates == discovered_check_candidates());
assert(is_ok(m));
assert(ci.dcCandidates == discovered_check_candidates());
- assert(color_of(piece_moved(m)) == side_to_move());
+ assert(color_of(piece_moved(m)) == sideToMove);
Square from = from_sq(m);
Square to = to_sq(m);
Square from = from_sq(m);
Square to = to_sq(m);
{
// For pawn and king moves we need to verify also direction
if ( (pt != PAWN && pt != KING)
{
// For pawn and king moves we need to verify also direction
if ( (pt != PAWN && pt != KING)
- || !squares_aligned(from, to, king_square(flip(side_to_move()))))
+ || !squares_aligned(from, to, king_square(~sideToMove)))
if (!is_special(m))
return false;
if (!is_special(m))
return false;
- Color us = side_to_move();
Bitboard b = occupied_squares();
Bitboard b = occupied_squares();
- Square ksq = king_square(flip(us));
+ Square ksq = king_square(~us);
// Promotion with check ?
if (is_promotion(m))
// Promotion with check ?
if (is_promotion(m))
- Color us = side_to_move();
- Color them = flip(us);
+ Color us = sideToMove;
+ Color them = ~us;
Square from = from_sq(m);
Square to = to_sq(m);
Piece piece = piece_on(from);
Square from = from_sq(m);
Square to = to_sq(m);
Piece piece = piece_on(from);
- sideToMove = flip(sideToMove);
+ sideToMove = ~sideToMove;
st->value += (sideToMove == WHITE ? TempoValue : -TempoValue);
assert(pos_is_ok());
st->value += (sideToMove == WHITE ? TempoValue : -TempoValue);
assert(pos_is_ok());
- sideToMove = flip(sideToMove);
+ sideToMove = ~sideToMove;
- Color us = side_to_move();
- Color them = flip(us);
+ Color us = sideToMove;
+ Color them = ~us;
Square from = from_sq(m);
Square to = to_sq(m);
Piece piece = piece_on(to);
Square from = from_sq(m);
Square to = to_sq(m);
Piece piece = piece_on(to);
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
- Color us = side_to_move();
Square kBefore = from_sq(m);
Square rBefore = to_sq(m);
Square kBefore = from_sq(m);
Square rBefore = to_sq(m);
st->rule50 = 0;
// Update checkers BB
st->rule50 = 0;
// Update checkers BB
- st->checkersBB = attackers_to(king_square(flip(us))) & pieces(us);
+ st->checkersBB = attackers_to(king_square(~us)) & pieces(us);
- sideToMove = flip(sideToMove);
+ sideToMove = ~sideToMove;
st->value += (sideToMove == WHITE ? TempoValue : -TempoValue);
}
else
st->value += (sideToMove == WHITE ? TempoValue : -TempoValue);
}
else
dst->rule50 = src->rule50;
dst->pliesFromNull = src->pliesFromNull;
dst->rule50 = src->rule50;
dst->pliesFromNull = src->pliesFromNull;
- sideToMove = flip(sideToMove);
+ sideToMove = ~sideToMove;
// Handle en passant moves
if (is_enpassant(m))
{
// Handle en passant moves
if (is_enpassant(m))
{
- Square capQq = to - pawn_push(side_to_move());
+ Square capQq = to - pawn_push(sideToMove);
assert(capturedType == NO_PIECE_TYPE);
assert(type_of(piece_on(capQq)) == PAWN);
assert(capturedType == NO_PIECE_TYPE);
assert(type_of(piece_on(capQq)) == PAWN);
attackers = attackers_to(to, occ);
// If the opponent has no attackers we are finished
attackers = attackers_to(to, occ);
// If the opponent has no attackers we are finished
- stm = flip(color_of(piece_on(from)));
+ stm = ~color_of(piece_on(from));
stmAttackers = attackers & pieces(stm);
if (!stmAttackers)
return PieceValueMidgame[capturedType];
stmAttackers = attackers & pieces(stm);
if (!stmAttackers)
return PieceValueMidgame[capturedType];
// Remember the value of the capturing piece, and change the side to
// move before beginning the next iteration.
capturedType = pt;
// Remember the value of the capturing piece, and change the side to
// move before beginning the next iteration.
capturedType = pt;
stmAttackers = attackers & pieces(stm);
// Stop before processing a king capture
stmAttackers = attackers & pieces(stm);
// Stop before processing a king capture
if (ep_square() != SQ_NONE)
result ^= zobEp[ep_square()];
if (ep_square() != SQ_NONE)
result ^= zobEp[ep_square()];
- if (side_to_move() == BLACK)
+ if (sideToMove == BLACK)
result ^= zobSideToMove;
return result;
result ^= zobSideToMove;
return result;
result += pst(make_piece(c, pt), pop_1st_bit(&b));
}
result += pst(make_piece(c, pt), pop_1st_bit(&b));
}
- result += (side_to_move() == WHITE ? TempoValue / 2 : -TempoValue / 2);
+ result += (sideToMove == WHITE ? TempoValue / 2 : -TempoValue / 2);
for (Square s = SQ_A1; s <= SQ_H8; s++)
{
pieceSquareTable[p][s] = ps + PSQT[p][s];
for (Square s = SQ_A1; s <= SQ_H8; s++)
{
pieceSquareTable[p][s] = ps + PSQT[p][s];
- pieceSquareTable[p+8][flip(s)] = -pieceSquareTable[p][s];
+ pieceSquareTable[p+8][~s] = -pieceSquareTable[p][s];
// Board
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.square_is_empty(s))
// Board
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.square_is_empty(s))
- put_piece(Piece(pos.piece_on(s) ^ 8), flip(s));
+ put_piece(Piece(pos.piece_on(s) ^ 8), ~s);
- sideToMove = flip(pos.side_to_move());
+ sideToMove = ~pos.side_to_move();
// Castling rights
if (pos.can_castle(WHITE_OO))
// Castling rights
if (pos.can_castle(WHITE_OO))
- set_castle_right(BLACK, flip(pos.castle_rook_square(WHITE_OO)));
+ set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OO));
if (pos.can_castle(WHITE_OOO))
if (pos.can_castle(WHITE_OOO))
- set_castle_right(BLACK, flip(pos.castle_rook_square(WHITE_OOO)));
+ set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OOO));
if (pos.can_castle(BLACK_OO))
if (pos.can_castle(BLACK_OO))
- set_castle_right(WHITE, flip(pos.castle_rook_square(BLACK_OO)));
+ set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OO));
if (pos.can_castle(BLACK_OOO))
if (pos.can_castle(BLACK_OOO))
- set_castle_right(WHITE, flip(pos.castle_rook_square(BLACK_OOO)));
+ set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OOO));
// En passant square
if (pos.st->epSquare != SQ_NONE)
// En passant square
if (pos.st->epSquare != SQ_NONE)
- st->epSquare = flip(pos.st->epSquare);
+ st->epSquare = ~pos.st->epSquare;
- st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(flip(sideToMove));
+ st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
// Hash keys
st->key = compute_key();
// Hash keys
st->key = compute_key();
if (failedStep) *failedStep = 1;
// Side to move OK?
if (failedStep) *failedStep = 1;
// Side to move OK?
- if (side_to_move() != WHITE && side_to_move() != BLACK)
+ if (sideToMove != WHITE && sideToMove != BLACK)
return false;
// Are the king squares in the position correct?
return false;
// Are the king squares in the position correct?
if (failedStep) (*failedStep)++;
if (debugKingCapture)
{
if (failedStep) (*failedStep)++;
if (debugKingCapture)
{
- Color us = side_to_move();
- Color them = flip(us);
+ Color us = sideToMove;
+ Color them = ~us;
Square ksq = king_square(them);
if (attackers_to(ksq) & pieces(us))
return false;
Square ksq = king_square(them);
if (attackers_to(ksq) & pieces(us))
return false;
{
// The en passant square must be on rank 6, from the point of view of the
// side to move.
{
// The en passant square must be on rank 6, from the point of view of the
// side to move.
- if (relative_rank(side_to_move(), ep_square()) != RANK_6)
+ if (relative_rank(sideToMove, ep_square()) != RANK_6)
}
inline bool Position::pawn_is_passed(Color c, Square s) const {
}
inline bool Position::pawn_is_passed(Color c, Square s) const {
- return !(pieces(PAWN, flip(c)) & passed_pawn_mask(c, s));
+ return !(pieces(PAWN, ~c) & passed_pawn_mask(c, s));
}
inline Key Position::key() const {
}
inline Key Position::key() const {
from = from_sq(move);
to = to_sq(move);
from = from_sq(move);
to = to_sq(move);
- them = flip(pos.side_to_move());
+ them = ~pos.side_to_move();
ksq = pos.king_square(them);
kingAtt = pos.attacks_from<KING>(ksq);
pc = pos.piece_on(from);
ksq = pos.king_square(them);
kingAtt = pos.attacks_from<KING>(ksq);
pc = pos.piece_on(from);
extern const Value PieceValueEndgame[17];
extern int SquareDistance[64][64];
extern const Value PieceValueEndgame[17];
extern int SquareDistance[64][64];
+inline Color operator~(Color c) {
+ return Color(c ^ 1);
+}
+
+inline Square operator~(Square s) {
+ return Square(s ^ 56);
+}
+
inline Value mate_in(int ply) {
return VALUE_MATE - ply;
}
inline Value mate_in(int ply) {
return VALUE_MATE - ply;
}
-inline Color flip(Color c) {
- return Color(c ^ 1);
-}
-
inline Square make_square(File f, Rank r) {
return Square((r << 3) | f);
}
inline Square make_square(File f, Rank r) {
return Square((r << 3) | f);
}
-inline Square flip(Square s) {
- return Square(s ^ 56);
-}
-
inline Square mirror(Square s) {
return Square(s ^ 7);
}
inline Square mirror(Square s) {
return Square(s ^ 7);
}