Needed to rename old MoveType (used in move generation)
to GenType.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
move = make_promotion(from_sq(move), to_sq(move), PieceType(pt + 1));
// Add 'special move' flags and verify it is legal
move = make_promotion(from_sq(move), to_sq(move), PieceType(pt + 1));
// Add 'special move' flags and verify it is legal
- for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
+ for (MoveList<LEGAL> ml(pos); !ml.end(); ++ml)
if (move == (ml.move() & 0x3FFF))
return ml.move();
if (move == (ml.move() & 0x3FFF))
return ml.move();
// Stalemate detection with lone king
if ( pos.side_to_move() == weakerSide
&& !pos.in_check()
// Stalemate detection with lone king
if ( pos.side_to_move() == weakerSide
&& !pos.in_check()
- && !MoveList<MV_LEGAL>(pos).size()) {
+ && !MoveList<LEGAL>(pos).size()) {
- template<MoveType Type, Square Delta>
+ template<GenType Type, Square Delta>
inline MoveStack* generate_promotions(MoveStack* mlist, Bitboard pawnsOn7, Bitboard target, Square ksq) {
Bitboard b = move_pawns<Delta>(pawnsOn7) & target;
inline MoveStack* generate_promotions(MoveStack* mlist, Bitboard pawnsOn7, Bitboard target, Square ksq) {
Bitboard b = move_pawns<Delta>(pawnsOn7) & target;
{
Square to = pop_1st_bit(&b);
{
Square to = pop_1st_bit(&b);
- if (Type == MV_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
+ if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
(*mlist++).move = make_promotion(to - Delta, to, QUEEN);
(*mlist++).move = make_promotion(to - Delta, to, QUEEN);
- if (Type == MV_QUIET || Type == MV_EVASION || Type == MV_NON_EVASION)
+ if (Type == QUIETS || Type == EVASIONS || Type == NON_EVASIONS)
{
(*mlist++).move = make_promotion(to - Delta, to, ROOK);
(*mlist++).move = make_promotion(to - Delta, to, BISHOP);
{
(*mlist++).move = make_promotion(to - Delta, to, ROOK);
(*mlist++).move = make_promotion(to - Delta, to, BISHOP);
// Knight-promotion is the only one that can give a direct check not
// already included in the queen-promotion.
// Knight-promotion is the only one that can give a direct check not
// already included in the queen-promotion.
- if (Type == MV_QUIET_CHECK && (StepAttacksBB[W_KNIGHT][to] & ksq))
+ if (Type == QUIET_CHECKS && (StepAttacksBB[W_KNIGHT][to] & ksq))
(*mlist++).move = make_promotion(to - Delta, to, KNIGHT);
else
(void)ksq; // Silence a warning under MSVC
(*mlist++).move = make_promotion(to - Delta, to, KNIGHT);
else
(void)ksq; // Silence a warning under MSVC
- template<Color Us, MoveType Type>
+ template<Color Us, GenType Type>
MoveStack* generate_pawn_moves(const Position& pos, MoveStack* mlist, Bitboard target, Square ksq = SQ_NONE) {
// Compute our parametrized parameters at compile time, named according to
MoveStack* generate_pawn_moves(const Position& pos, MoveStack* mlist, Bitboard target, Square ksq = SQ_NONE) {
// Compute our parametrized parameters at compile time, named according to
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
- Bitboard enemies = (Type == MV_EVASION ? pos.pieces(Them) & target:
- Type == MV_CAPTURE ? target : pos.pieces(Them));
+ Bitboard enemies = (Type == EVASIONS ? pos.pieces(Them) & target:
+ Type == CAPTURES ? target : pos.pieces(Them));
// Single and double pawn pushes, no promotions
// Single and double pawn pushes, no promotions
- if (Type != MV_CAPTURE)
- emptySquares = (Type == MV_QUIET ? target : ~pos.pieces());
+ emptySquares = (Type == QUIETS ? target : ~pos.pieces());
b1 = move_pawns<UP>(pawnsNotOn7) & emptySquares;
b2 = move_pawns<UP>(b1 & TRank3BB) & emptySquares;
b1 = move_pawns<UP>(pawnsNotOn7) & emptySquares;
b2 = move_pawns<UP>(b1 & TRank3BB) & emptySquares;
- if (Type == MV_EVASION) // Consider only blocking squares
+ if (Type == EVASIONS) // Consider only blocking squares
{
b1 &= target;
b2 &= target;
}
{
b1 &= target;
b2 &= target;
}
- if (Type == MV_QUIET_CHECK)
+ if (Type == QUIET_CHECKS)
{
b1 &= pos.attacks_from<PAWN>(ksq, Them);
b2 &= pos.attacks_from<PAWN>(ksq, Them);
{
b1 &= pos.attacks_from<PAWN>(ksq, Them);
b2 &= pos.attacks_from<PAWN>(ksq, Them);
}
// Promotions and underpromotions
}
// Promotions and underpromotions
- if (pawnsOn7 && (Type != MV_EVASION || (target & TRank8BB)))
+ if (pawnsOn7 && (Type != EVASIONS || (target & TRank8BB)))
- if (Type == MV_CAPTURE)
emptySquares = ~pos.pieces();
emptySquares = ~pos.pieces();
- if (Type == MV_EVASION)
emptySquares &= target;
mlist = generate_promotions<Type, RIGHT>(mlist, pawnsOn7, enemies, ksq);
emptySquares &= target;
mlist = generate_promotions<Type, RIGHT>(mlist, pawnsOn7, enemies, ksq);
}
// Standard and en-passant captures
}
// Standard and en-passant captures
- if (Type == MV_CAPTURE || Type == MV_EVASION || Type == MV_NON_EVASION)
+ if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
{
b1 = move_pawns<RIGHT>(pawnsNotOn7) & enemies;
b2 = move_pawns<LEFT >(pawnsNotOn7) & enemies;
{
b1 = move_pawns<RIGHT>(pawnsNotOn7) & enemies;
b2 = move_pawns<LEFT >(pawnsNotOn7) & enemies;
// An en passant capture can be an evasion only if the checking piece
// is the double pushed pawn and so is in the target. Otherwise this
// is a discovery check and we are forced to do otherwise.
// An en passant capture can be an evasion only if the checking piece
// is the double pushed pawn and so is in the target. Otherwise this
// is a discovery check and we are forced to do otherwise.
- if (Type == MV_EVASION && !(target & (pos.ep_square() - UP)))
+ if (Type == EVASIONS && !(target & (pos.ep_square() - UP)))
return mlist;
b1 = pawnsNotOn7 & pos.attacks_from<PAWN>(pos.ep_square(), Them);
return mlist;
b1 = pawnsNotOn7 & pos.attacks_from<PAWN>(pos.ep_square(), Them);
-/// generate<MV_CAPTURE> generates all pseudo-legal captures and queen
+/// generate<CAPTURES> generates all pseudo-legal captures and queen
/// promotions. Returns a pointer to the end of the move list.
///
/// promotions. Returns a pointer to the end of the move list.
///
-/// generate<MV_QUIET> generates all pseudo-legal non-captures and
+/// generate<QUIETS> generates all pseudo-legal non-captures and
/// underpromotions. Returns a pointer to the end of the move list.
///
/// underpromotions. Returns a pointer to the end of the move list.
///
-/// generate<MV_NON_EVASION> generates all pseudo-legal captures and
+/// generate<NON_EVASIONS> generates all pseudo-legal captures and
/// non-captures. Returns a pointer to the end of the move list.
/// non-captures. Returns a pointer to the end of the move list.
MoveStack* generate(const Position& pos, MoveStack* mlist) {
MoveStack* generate(const Position& pos, MoveStack* mlist) {
- assert(Type == MV_CAPTURE || Type == MV_QUIET || Type == MV_NON_EVASION);
+ assert(Type == CAPTURES || Type == QUIETS || Type == NON_EVASIONS);
assert(!pos.in_check());
Color us = pos.side_to_move();
Bitboard target;
assert(!pos.in_check());
Color us = pos.side_to_move();
Bitboard target;
- if (Type == MV_CAPTURE)
target = pos.pieces(~us);
target = pos.pieces(~us);
- else if (Type == MV_QUIET)
+ else if (Type == QUIETS)
- else if (Type == MV_NON_EVASION)
+ else if (Type == NON_EVASIONS)
target = ~pos.pieces(us);
mlist = (us == WHITE ? generate_pawn_moves<WHITE, Type>(pos, mlist, target)
target = ~pos.pieces(us);
mlist = (us == WHITE ? generate_pawn_moves<WHITE, Type>(pos, mlist, target)
mlist = generate_moves<QUEEN>(pos, mlist, us, target);
mlist = generate_moves<KING>(pos, mlist, us, target);
mlist = generate_moves<QUEEN>(pos, mlist, us, target);
mlist = generate_moves<KING>(pos, mlist, us, target);
- if (Type != MV_CAPTURE && pos.can_castle(us))
+ if (Type != CAPTURES && pos.can_castle(us))
{
mlist = generate_castle<KING_SIDE, false>(pos, mlist, us);
mlist = generate_castle<QUEEN_SIDE, false>(pos, mlist, us);
{
mlist = generate_castle<KING_SIDE, false>(pos, mlist, us);
mlist = generate_castle<QUEEN_SIDE, false>(pos, mlist, us);
}
// Explicit template instantiations
}
// Explicit template instantiations
-template MoveStack* generate<MV_CAPTURE>(const Position& pos, MoveStack* mlist);
-template MoveStack* generate<MV_QUIET>(const Position& pos, MoveStack* mlist);
-template MoveStack* generate<MV_NON_EVASION>(const Position& pos, MoveStack* mlist);
+template MoveStack* generate<CAPTURES>(const Position& pos, MoveStack* mlist);
+template MoveStack* generate<QUIETS>(const Position& pos, MoveStack* mlist);
+template MoveStack* generate<NON_EVASIONS>(const Position& pos, MoveStack* mlist);
-/// generate<MV_QUIET_CHECK> generates all pseudo-legal non-captures and knight
+/// generate<QUIET_CHECKS> generates all pseudo-legal non-captures and knight
/// underpromotions that give check. Returns a pointer to the end of the move list.
template<>
/// underpromotions that give check. Returns a pointer to the end of the move list.
template<>
-MoveStack* generate<MV_QUIET_CHECK>(const Position& pos, MoveStack* mlist) {
+MoveStack* generate<QUIET_CHECKS>(const Position& pos, MoveStack* mlist) {
- mlist = (us == WHITE ? generate_pawn_moves<WHITE, MV_QUIET_CHECK>(pos, mlist, ci.dcCandidates, ci.ksq)
- : generate_pawn_moves<BLACK, MV_QUIET_CHECK>(pos, mlist, ci.dcCandidates, ci.ksq));
+ mlist = (us == WHITE ? generate_pawn_moves<WHITE, QUIET_CHECKS>(pos, mlist, ci.dcCandidates, ci.ksq)
+ : generate_pawn_moves<BLACK, QUIET_CHECKS>(pos, mlist, ci.dcCandidates, ci.ksq));
mlist = generate_direct_checks<KNIGHT>(pos, mlist, us, ci);
mlist = generate_direct_checks<BISHOP>(pos, mlist, us, ci);
mlist = generate_direct_checks<KNIGHT>(pos, mlist, us, ci);
mlist = generate_direct_checks<BISHOP>(pos, mlist, us, ci);
-/// generate<MV_EVASION> generates all pseudo-legal check evasions when the side
+/// generate<EVASIONS> generates all pseudo-legal check evasions when the side
/// to move is in check. Returns a pointer to the end of the move list.
template<>
/// to move is in check. Returns a pointer to the end of the move list.
template<>
-MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
+MoveStack* generate<EVASIONS>(const Position& pos, MoveStack* mlist) {
// Blocking evasions or captures of the checking piece
target = between_bb(checksq, ksq) | checkers;
// Blocking evasions or captures of the checking piece
target = between_bb(checksq, ksq) | checkers;
- mlist = (us == WHITE ? generate_pawn_moves<WHITE, MV_EVASION>(pos, mlist, target)
- : generate_pawn_moves<BLACK, MV_EVASION>(pos, mlist, target));
+ mlist = (us == WHITE ? generate_pawn_moves<WHITE, EVASIONS>(pos, mlist, target)
+ : generate_pawn_moves<BLACK, EVASIONS>(pos, mlist, target));
mlist = generate_moves<KNIGHT>(pos, mlist, us, target);
mlist = generate_moves<BISHOP>(pos, mlist, us, target);
mlist = generate_moves<KNIGHT>(pos, mlist, us, target);
mlist = generate_moves<BISHOP>(pos, mlist, us, target);
-/// generate<MV_LEGAL> generates all the legal moves in the given position
+/// generate<LEGAL> generates all the legal moves in the given position
-MoveStack* generate<MV_LEGAL>(const Position& pos, MoveStack* mlist) {
+MoveStack* generate<LEGAL>(const Position& pos, MoveStack* mlist) {
MoveStack *last, *cur = mlist;
Bitboard pinned = pos.pinned_pieces();
MoveStack *last, *cur = mlist;
Bitboard pinned = pos.pinned_pieces();
- last = pos.in_check() ? generate<MV_EVASION>(pos, mlist)
- : generate<MV_NON_EVASION>(pos, mlist);
+ last = pos.in_check() ? generate<EVASIONS>(pos, mlist)
+ : generate<NON_EVASIONS>(pos, mlist);
while (cur != last)
if (!pos.pl_move_is_legal(cur->move, pinned))
cur->move = (--last)->move;
while (cur != last)
if (!pos.pl_move_is_legal(cur->move, pinned))
cur->move = (--last)->move;
-enum MoveType {
- MV_CAPTURE,
- MV_QUIET,
- MV_QUIET_CHECK,
- MV_EVASION,
- MV_NON_EVASION,
- MV_LEGAL
+enum GenType {
+ CAPTURES,
+ QUIETS,
+ QUIET_CHECKS,
+ EVASIONS,
+ NON_EVASIONS,
+ LEGAL
MoveStack* generate(const Position& pos, MoveStack* mlist);
/// The MoveList struct is a simple wrapper around generate(), sometimes comes
/// handy to use this class instead of the low level generate() function.
MoveStack* generate(const Position& pos, MoveStack* mlist);
/// The MoveList struct is a simple wrapper around generate(), sometimes comes
/// handy to use this class instead of the low level generate() function.
struct MoveList {
explicit MoveList(const Position& pos) : cur(mlist), last(generate<T>(pos, mlist)) {}
struct MoveList {
explicit MoveList(const Position& pos) : cur(mlist), last(generate<T>(pos, mlist)) {}
cur->score = PieceValueMidgame[pos.piece_on(to_sq(m))]
- type_of(pos.piece_moved(m));
cur->score = PieceValueMidgame[pos.piece_on(to_sq(m))]
- type_of(pos.piece_moved(m));
+ if (type_of(m) == PROMOTION)
cur->score += PieceValueMidgame[promotion_type(m)];
}
}
cur->score += PieceValueMidgame[promotion_type(m)];
}
}
switch (++phase) {
case CAPTURES_S1: case CAPTURES_S3: case CAPTURES_S4: case CAPTURES_S5: case CAPTURES_S6:
switch (++phase) {
case CAPTURES_S1: case CAPTURES_S3: case CAPTURES_S4: case CAPTURES_S5: case CAPTURES_S6:
- lastMove = generate<MV_CAPTURE>(pos, moves);
+ lastMove = generate<CAPTURES>(pos, moves);
score_captures();
return;
score_captures();
return;
return;
case QUIETS_1_S1:
return;
case QUIETS_1_S1:
- lastQuiet = lastMove = generate<MV_QUIET>(pos, moves);
+ lastQuiet = lastMove = generate<QUIETS>(pos, moves);
score_noncaptures();
lastMove = std::partition(curMove, lastMove, has_positive_score);
sort<MoveStack>(curMove, lastMove);
score_noncaptures();
lastMove = std::partition(curMove, lastMove, has_positive_score);
sort<MoveStack>(curMove, lastMove);
return;
case EVASIONS_S2:
return;
case EVASIONS_S2:
- lastMove = generate<MV_EVASION>(pos, moves);
+ lastMove = generate<EVASIONS>(pos, moves);
score_evasions();
return;
case QUIET_CHECKS_S3:
score_evasions();
return;
case QUIET_CHECKS_S3:
- lastMove = generate<MV_QUIET_CHECK>(pos, moves);
+ lastMove = generate<QUIET_CHECKS>(pos, moves);
return;
case EVASION: case QSEARCH_0: case QSEARCH_1: case PROBCUT: case RECAPTURE:
return;
case EVASION: case QSEARCH_0: case QSEARCH_1: case PROBCUT: case RECAPTURE:
Square from = from_sq(m);
Square to = to_sq(m);
Square from = from_sq(m);
Square to = to_sq(m);
if (m == MOVE_NONE)
return "(none)";
if (m == MOVE_NONE)
return "(none)";
if (m == MOVE_NULL)
return "0000";
if (m == MOVE_NULL)
return "0000";
- if (is_castle(m) && !chess960)
+ if (type_of(m) == CASTLE && !chess960)
to = (to > from ? FILE_G : FILE_C) | rank_of(from);
to = (to > from ? FILE_G : FILE_C) | rank_of(from);
- if (is_promotion(m))
- promotion = char(tolower(piece_type_to_char(promotion_type(m))));
+ string move = square_to_string(from) + square_to_string(to);
- return square_to_string(from) + square_to_string(to) + promotion;
+ if (type_of(m) == PROMOTION)
+ move += char(tolower(piece_type_to_char(promotion_type(m))));
+
+ return move;
if (str.length() == 5) // Junior could send promotion piece in uppercase
str[4] = char(tolower(str[4]));
if (str.length() == 5) // Junior could send promotion piece in uppercase
str[4] = char(tolower(str[4]));
- for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
+ for (MoveList<LEGAL> ml(pos); !ml.end(); ++ml)
if (str == move_to_uci(ml.move(), pos.is_chess960()))
return ml.move();
if (str == move_to_uci(ml.move(), pos.is_chess960()))
return ml.move();
Square to = to_sq(m);
PieceType pt = type_of(pos.piece_on(from));
Square to = to_sq(m);
PieceType pt = type_of(pos.piece_on(from));
+ if (type_of(m) == CASTLE)
san = to > from ? "O-O" : "O-O-O";
else
{
san = to > from ? "O-O" : "O-O-O";
else
{
san += square_to_string(to);
san += square_to_string(to);
+ if (type_of(m) == PROMOTION)
san += string("=") + piece_type_to_char(promotion_type(m));
}
san += string("=") + piece_type_to_char(promotion_type(m));
}
{
StateInfo st;
pos.do_move(m, st);
{
StateInfo st;
pos.do_move(m, st);
- san += MoveList<MV_LEGAL>(pos).size() ? "+" : "#";
+ san += MoveList<LEGAL>(pos).size() ? "+" : "#";
// En passant captures are a tricky special case. Because they are rather
// uncommon, we do it simply by testing whether the king is attacked after
// the move is made.
// En passant captures are a tricky special case. Because they are rather
// uncommon, we do it simply by testing whether the king is attacked after
// the move is made.
+ if (type_of(m) == ENPASSANT)
{
Color them = ~us;
Square to = to_sq(m);
{
Color them = ~us;
Square to = to_sq(m);
// 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(~us));
+ return type_of(m) == CASTLE || !(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::move_is_legal(const Move m) const {
bool Position::move_is_legal(const Move m) const {
- for (MoveList<MV_LEGAL> ml(*this); !ml.end(); ++ml)
+ for (MoveList<LEGAL> ml(*this); !ml.end(); ++ml)
if (ml.move() == m)
return true;
if (ml.move() == m)
return true;
Piece pc = piece_moved(m);
// Use a slower but simpler function for uncommon cases
Piece pc = piece_moved(m);
// Use a slower but simpler function for uncommon cases
+ if (type_of(m) != NORMAL)
return move_is_legal(m);
// Is not a promotion, so promotion piece must be empty
return move_is_legal(m);
// Is not a promotion, so promotion piece must be empty
}
// Can we skip the ugly special cases ?
}
// Can we skip the ugly special cases ?
+ if (type_of(m) == NORMAL)
return false;
Color us = sideToMove;
Square ksq = king_square(~us);
// Promotion with check ?
return false;
Color us = sideToMove;
Square ksq = king_square(~us);
// Promotion with check ?
+ if (type_of(m) == PROMOTION)
return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq;
// En passant capture with check ? We have already handled the case
// of direct checks and ordinary discovered check, the only case we
// need to handle is the unusual case of a discovered check through
// the captured pawn.
return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq;
// En passant capture with check ? We have already handled the case
// of direct checks and ordinary discovered check, the only case we
// need to handle is the unusual case of a discovered check through
// the captured pawn.
+ if (type_of(m) == ENPASSANT)
{
Square capsq = file_of(to) | rank_of(from);
Bitboard b = (pieces() ^ from ^ capsq) | to;
{
Square capsq = file_of(to) | rank_of(from);
Bitboard b = (pieces() ^ from ^ capsq) | to;
}
// Castling with check ?
}
// Castling with check ?
+ if (type_of(m) == CASTLE)
{
Square kfrom = from;
Square rfrom = to; // 'King captures the rook' notation
{
Square kfrom = from;
Square rfrom = to; // 'King captures the rook' notation
st->rule50++;
st->pliesFromNull++;
st->rule50++;
st->pliesFromNull++;
+ if (type_of(m) == CASTLE)
{
st->key = k;
do_castle_move<true>(m);
{
st->key = k;
do_castle_move<true>(m);
Square to = to_sq(m);
Piece piece = piece_on(from);
PieceType pt = type_of(piece);
Square to = to_sq(m);
Piece piece = piece_on(from);
PieceType pt = type_of(piece);
- PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
+ PieceType capture = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
assert(color_of(piece) == us);
assert(color_of(piece_on(to)) != us);
assert(color_of(piece) == us);
assert(color_of(piece_on(to)) != us);
// update non-pawn material.
if (capture == PAWN)
{
// update non-pawn material.
if (capture == PAWN)
{
+ if (type_of(m) == ENPASSANT)
{
capsq += pawn_push(them);
{
capsq += pawn_push(them);
k ^= zobEp[file_of(st->epSquare)];
}
k ^= zobEp[file_of(st->epSquare)];
}
+ if (type_of(m) == PROMOTION)
{
PieceType promotion = promotion_type(m);
{
PieceType promotion = promotion_type(m);
+ if (type_of(m) != NORMAL)
st->checkersBB = attackers_to(king_square(them)) & pieces(us);
else
{
st->checkersBB = attackers_to(king_square(them)) & pieces(us);
else
{
sideToMove = ~sideToMove;
sideToMove = ~sideToMove;
+ if (type_of(m) == CASTLE)
{
do_castle_move<false>(m);
return;
{
do_castle_move<false>(m);
return;
assert(color_of(piece) == us);
assert(capture != KING);
assert(color_of(piece) == us);
assert(capture != KING);
+ if (type_of(m) == PROMOTION)
{
PieceType promotion = promotion_type(m);
{
PieceType promotion = promotion_type(m);
+ if (type_of(m) == ENPASSANT)
{
capsq -= pawn_push(us);
{
capsq -= pawn_push(us);
void Position::do_castle_move(Move m) {
assert(is_ok(m));
void Position::do_castle_move(Move m) {
assert(is_ok(m));
+ assert(type_of(m) == CASTLE);
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
// As castle moves are implemented as capturing the rook, they have
// SEE == RookValueMidgame most of the times (unless the rook is under
// attack).
// As castle moves are implemented as capturing the rook, they have
// SEE == RookValueMidgame most of the times (unless the rook is under
// attack).
+ if (type_of(m) == CASTLE)
return 0;
from = from_sq(m);
return 0;
from = from_sq(m);
occ = pieces();
// Handle en passant moves
occ = pieces();
// Handle en passant moves
+ if (type_of(m) == ENPASSANT)
{
Square capQq = to - pawn_push(sideToMove);
{
Square capQq = to - pawn_push(sideToMove);
return true;
// Draw by the 50 moves rule?
return true;
// Draw by the 50 moves rule?
- if (st->rule50 > 99 && (!in_check() || MoveList<MV_LEGAL>(*this).size()))
+ if (st->rule50 > 99 && (!in_check() || MoveList<LEGAL>(*this).size()))
return true;
// Draw by repetition?
return true;
// Draw by repetition?
inline bool Position::is_capture_or_promotion(Move m) const {
assert(is_ok(m));
inline bool Position::is_capture_or_promotion(Move m) const {
assert(is_ok(m));
- return is_special(m) ? !is_castle(m) : !is_empty(to_sq(m));
+ return type_of(m) ? type_of(m) != CASTLE : !is_empty(to_sq(m));
}
inline bool Position::is_capture(Move m) const {
// Note that castle is coded as "king captures the rook"
assert(is_ok(m));
}
inline bool Position::is_capture(Move m) const {
// Note that castle is coded as "king captures the rook"
assert(is_ok(m));
- return (!is_empty(to_sq(m)) && !is_castle(m)) || is_enpassant(m);
+ return (!is_empty(to_sq(m)) && type_of(m) != CASTLE) || type_of(m) == ENPASSANT;
}
inline PieceType Position::captured_piece_type() const {
}
inline PieceType Position::captured_piece_type() const {
// Test for a capture that triggers a pawn endgame
if ( captureOrPromotion
&& type_of(pos.piece_on(to_sq(m))) != PAWN
// Test for a capture that triggers a pawn endgame
if ( captureOrPromotion
&& type_of(pos.piece_on(to_sq(m))) != PAWN
+ && type_of(m) == NORMAL
&& ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
- PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO))
return true;
&& ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
- PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO))
return true;
StateInfo st;
int64_t cnt = 0;
StateInfo st;
int64_t cnt = 0;
- MoveList<MV_LEGAL> ml(pos);
+ MoveList<LEGAL> ml(pos);
// At the last ply just return the number of moves (leaf nodes)
if (depth == ONE_PLY)
// At the last ply just return the number of moves (leaf nodes)
if (depth == ONE_PLY)
&& (ss-1)->eval != VALUE_NONE
&& ss->eval != VALUE_NONE
&& !pos.captured_piece_type()
&& (ss-1)->eval != VALUE_NONE
&& ss->eval != VALUE_NONE
&& !pos.captured_piece_type()
+ && type_of(move) == NORMAL)
{
Square to = to_sq(move);
H.update_gain(pos.piece_on(to), to, -(ss-1)->eval - ss->eval);
{
Square to = to_sq(move);
H.update_gain(pos.piece_on(to), to, -(ss-1)->eval - ss->eval);
&& !inCheck
&& !dangerous
&& move != ttMove
&& !inCheck
&& !dangerous
&& move != ttMove
+ && type_of(move) != CASTLE
&& (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE))
{
// Move count based pruning
&& (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE))
{
// Move count based pruning
&& !isPvMove
&& !captureOrPromotion
&& !dangerous
&& !isPvMove
&& !captureOrPromotion
&& !dangerous
+ && type_of(move) != CASTLE
&& ss->killers[0] != move
&& ss->killers[1] != move)
{
&& ss->killers[0] != move
&& ss->killers[1] != move)
{
&& !givesCheck
&& move != ttMove
&& enoughMaterial
&& !givesCheck
&& move != ttMove
&& enoughMaterial
+ && type_of(move) != PROMOTION
&& !pos.is_passed_pawn_push(move))
{
futilityValue = futilityBase
+ PieceValueEndgame[pos.piece_on(to_sq(move))]
&& !pos.is_passed_pawn_push(move))
{
futilityValue = futilityBase
+ PieceValueEndgame[pos.piece_on(to_sq(move))]
- + (is_enpassant(move) ? PawnValueEndgame : VALUE_ZERO);
+ + (type_of(move) == ENPASSANT ? PawnValueEndgame : VALUE_ZERO);
if (futilityValue < beta)
{
if (futilityValue < beta)
{
if ( !PvNode
&& (!inCheck || evasionPrunable)
&& move != ttMove
if ( !PvNode
&& (!inCheck || evasionPrunable)
&& move != ttMove
+ && type_of(move) != PROMOTION
&& pos.see_sign(move) < 0)
continue;
&& pos.see_sign(move) < 0)
continue;
Limits = limits;
RootMoves.clear();
Limits = limits;
RootMoves.clear();
- for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
+ for (MoveList<LEGAL> ml(pos); !ml.end(); ++ml)
if (searchMoves.empty() || count(searchMoves.begin(), searchMoves.end(), ml.move()))
RootMoves.push_back(RootMove(ml.move()));
if (searchMoves.empty() || count(searchMoves.begin(), searchMoves.end(), ml.move()))
RootMoves.push_back(RootMove(ml.move()));
-struct MoveStack {
- Move move;
- int score;
+enum MoveType {
+ NORMAL = 0,
+ PROMOTION = 1 << 14,
+ ENPASSANT = 2 << 14,
+ CASTLE = 3 << 14
-inline bool operator<(const MoveStack& f, const MoveStack& s) {
- return f.score < s.score;
-}
-
enum CastleRight { // Defined as in PolyGlot book hash key
CASTLES_NONE = 0,
WHITE_OO = 1,
enum CastleRight { // Defined as in PolyGlot book hash key
CASTLES_NONE = 0,
WHITE_OO = 1,
extern const Value PieceValueEndgame[17];
extern int SquareDistance[64][64];
extern const Value PieceValueEndgame[17];
extern int SquareDistance[64][64];
+struct MoveStack {
+ Move move;
+ int score;
+};
+
+inline bool operator<(const MoveStack& f, const MoveStack& s) {
+ return f.score < s.score;
+}
+
inline Color operator~(Color c) {
return Color(c ^ 1);
}
inline Color operator~(Color c) {
return Color(c ^ 1);
}
return Square(m & 0x3F);
}
return Square(m & 0x3F);
}
-inline bool is_special(Move m) {
- return m & (3 << 14);
-}
-
-inline bool is_promotion(Move m) {
- return (m & (3 << 14)) == (1 << 14);
-}
-
-inline int is_enpassant(Move m) {
- return (m & (3 << 14)) == (2 << 14);
-}
-
-inline int is_castle(Move m) {
- return (m & (3 << 14)) == (3 << 14);
+inline MoveType type_of(Move m) {
+ return MoveType(m & (3 << 14));
}
inline PieceType promotion_type(Move m) {
}
inline PieceType promotion_type(Move m) {