mirror of
https://github.com/sockspls/badfish
synced 2025-05-02 09:39:36 +00:00
Use type_of() to categorize the moves
Needed to rename old MoveType (used in move generation) to GenType. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
7b4aa10708
commit
dc7fd868f4
11 changed files with 113 additions and 117 deletions
|
@ -445,7 +445,7 @@ Move Book::probe(const Position& pos, const string& fName, bool pickBest) {
|
|||
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();
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ Value Endgame<KXK>::operator()(const Position& pos) const {
|
|||
// Stalemate detection with lone king
|
||||
if ( pos.side_to_move() == weakerSide
|
||||
&& !pos.in_check()
|
||||
&& !MoveList<MV_LEGAL>(pos).size()) {
|
||||
&& !MoveList<LEGAL>(pos).size()) {
|
||||
return VALUE_DRAW;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
|
@ -89,10 +89,10 @@ namespace {
|
|||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -101,7 +101,7 @@ namespace {
|
|||
|
||||
// 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
|
||||
|
@ -111,7 +111,7 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -129,24 +129,24 @@ namespace {
|
|||
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
|
||||
if (Type != MV_CAPTURE)
|
||||
if (Type != CAPTURES)
|
||||
{
|
||||
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;
|
||||
|
||||
if (Type == MV_EVASION) // Consider only blocking squares
|
||||
if (Type == EVASIONS) // Consider only blocking squares
|
||||
{
|
||||
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);
|
||||
|
@ -170,12 +170,12 @@ namespace {
|
|||
}
|
||||
|
||||
// Promotions and underpromotions
|
||||
if (pawnsOn7 && (Type != MV_EVASION || (target & TRank8BB)))
|
||||
if (pawnsOn7 && (Type != EVASIONS || (target & TRank8BB)))
|
||||
{
|
||||
if (Type == MV_CAPTURE)
|
||||
if (Type == CAPTURES)
|
||||
emptySquares = ~pos.pieces();
|
||||
|
||||
if (Type == MV_EVASION)
|
||||
if (Type == EVASIONS)
|
||||
emptySquares &= target;
|
||||
|
||||
mlist = generate_promotions<Type, RIGHT>(mlist, pawnsOn7, enemies, ksq);
|
||||
|
@ -184,7 +184,7 @@ namespace {
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
@ -199,7 +199,7 @@ namespace {
|
|||
// 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);
|
||||
|
@ -279,31 +279,31 @@ namespace {
|
|||
} // namespace
|
||||
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
|
||||
template<MoveType Type>
|
||||
template<GenType Type>
|
||||
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;
|
||||
|
||||
if (Type == MV_CAPTURE)
|
||||
if (Type == CAPTURES)
|
||||
target = pos.pieces(~us);
|
||||
|
||||
else if (Type == MV_QUIET)
|
||||
else if (Type == QUIETS)
|
||||
target = ~pos.pieces();
|
||||
|
||||
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)
|
||||
|
@ -315,7 +315,7 @@ MoveStack* generate(const Position& pos, MoveStack* mlist) {
|
|||
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);
|
||||
|
@ -325,15 +325,15 @@ MoveStack* generate(const Position& pos, MoveStack* mlist) {
|
|||
}
|
||||
|
||||
// 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<>
|
||||
MoveStack* generate<MV_QUIET_CHECK>(const Position& pos, MoveStack* mlist) {
|
||||
MoveStack* generate<QUIET_CHECKS>(const Position& pos, MoveStack* mlist) {
|
||||
|
||||
assert(!pos.in_check());
|
||||
|
||||
|
@ -357,8 +357,8 @@ MoveStack* generate<MV_QUIET_CHECK>(const Position& pos, MoveStack* mlist) {
|
|||
SERIALIZE(b);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -375,10 +375,10 @@ MoveStack* generate<MV_QUIET_CHECK>(const Position& pos, MoveStack* mlist) {
|
|||
}
|
||||
|
||||
|
||||
/// 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<>
|
||||
MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
|
||||
MoveStack* generate<EVASIONS>(const Position& pos, MoveStack* mlist) {
|
||||
|
||||
assert(pos.in_check());
|
||||
|
||||
|
@ -436,8 +436,8 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
|
|||
// 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);
|
||||
|
@ -446,16 +446,16 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
|
|||
}
|
||||
|
||||
|
||||
/// generate<MV_LEGAL> generates all the legal moves in the given position
|
||||
/// generate<LEGAL> generates all the legal moves in the given position
|
||||
|
||||
template<>
|
||||
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();
|
||||
|
||||
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;
|
||||
|
|
|
@ -22,23 +22,23 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
class Position;
|
||||
|
||||
template<MoveType>
|
||||
template<GenType>
|
||||
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.
|
||||
template<MoveType T>
|
||||
template<GenType T>
|
||||
struct MoveList {
|
||||
|
||||
explicit MoveList(const Position& pos) : cur(mlist), last(generate<T>(pos, mlist)) {}
|
||||
|
|
|
@ -166,7 +166,7 @@ void MovePicker::score_captures() {
|
|||
cur->score = PieceValueMidgame[pos.piece_on(to_sq(m))]
|
||||
- type_of(pos.piece_moved(m));
|
||||
|
||||
if (is_promotion(m))
|
||||
if (type_of(m) == PROMOTION)
|
||||
cur->score += PieceValueMidgame[promotion_type(m)];
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ void MovePicker::generate_next() {
|
|||
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;
|
||||
|
||||
|
@ -226,7 +226,7 @@ void MovePicker::generate_next() {
|
|||
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);
|
||||
|
@ -246,12 +246,12 @@ void MovePicker::generate_next() {
|
|||
return;
|
||||
|
||||
case EVASIONS_S2:
|
||||
lastMove = generate<MV_EVASION>(pos, moves);
|
||||
lastMove = generate<EVASIONS>(pos, moves);
|
||||
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:
|
||||
|
|
|
@ -34,7 +34,6 @@ const string move_to_uci(Move m, bool chess960) {
|
|||
|
||||
Square from = from_sq(m);
|
||||
Square to = to_sq(m);
|
||||
string promotion;
|
||||
|
||||
if (m == MOVE_NONE)
|
||||
return "(none)";
|
||||
|
@ -42,13 +41,15 @@ const string move_to_uci(Move m, bool chess960) {
|
|||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,7 +61,7 @@ Move move_from_uci(const Position& pos, string& str) {
|
|||
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();
|
||||
|
||||
|
@ -88,7 +89,7 @@ const string move_to_san(Position& pos, Move m) {
|
|||
Square to = to_sq(m);
|
||||
PieceType pt = type_of(pos.piece_on(from));
|
||||
|
||||
if (is_castle(m))
|
||||
if (type_of(m) == CASTLE)
|
||||
san = to > from ? "O-O" : "O-O-O";
|
||||
else
|
||||
{
|
||||
|
@ -138,7 +139,7 @@ const string move_to_san(Position& pos, Move m) {
|
|||
|
||||
san += square_to_string(to);
|
||||
|
||||
if (is_promotion(m))
|
||||
if (type_of(m) == PROMOTION)
|
||||
san += string("=") + piece_type_to_char(promotion_type(m));
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ const string move_to_san(Position& pos, Move m) {
|
|||
{
|
||||
StateInfo st;
|
||||
pos.do_move(m, st);
|
||||
san += MoveList<MV_LEGAL>(pos).size() ? "+" : "#";
|
||||
san += MoveList<LEGAL>(pos).size() ? "+" : "#";
|
||||
pos.undo_move(m);
|
||||
}
|
||||
|
||||
|
|
|
@ -448,7 +448,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
|
|||
// 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 (is_enpassant(m))
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
Color them = ~us;
|
||||
Square to = to_sq(m);
|
||||
|
@ -469,7 +469,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
|
|||
// 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.
|
||||
|
@ -485,7 +485,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) 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;
|
||||
|
||||
|
@ -506,7 +506,7 @@ bool Position::is_pseudo_legal(const Move m) const {
|
|||
Piece pc = piece_moved(m);
|
||||
|
||||
// Use a slower but simpler function for uncommon cases
|
||||
if (is_special(m))
|
||||
if (type_of(m) != NORMAL)
|
||||
return move_is_legal(m);
|
||||
|
||||
// Is not a promotion, so promotion piece must be empty
|
||||
|
@ -640,21 +640,21 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
|
|||
}
|
||||
|
||||
// Can we skip the ugly special cases ?
|
||||
if (!is_special(m))
|
||||
if (type_of(m) == NORMAL)
|
||||
return false;
|
||||
|
||||
Color us = sideToMove;
|
||||
Square ksq = king_square(~us);
|
||||
|
||||
// Promotion with check ?
|
||||
if (is_promotion(m))
|
||||
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.
|
||||
if (is_enpassant(m))
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
Square capsq = file_of(to) | rank_of(from);
|
||||
Bitboard b = (pieces() ^ from ^ capsq) | to;
|
||||
|
@ -664,7 +664,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
|
|||
}
|
||||
|
||||
// Castling with check ?
|
||||
if (is_castle(m))
|
||||
if (type_of(m) == CASTLE)
|
||||
{
|
||||
Square kfrom = from;
|
||||
Square rfrom = to; // 'King captures the rook' notation
|
||||
|
@ -713,7 +713,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
st->rule50++;
|
||||
st->pliesFromNull++;
|
||||
|
||||
if (is_castle(m))
|
||||
if (type_of(m) == CASTLE)
|
||||
{
|
||||
st->key = k;
|
||||
do_castle_move<true>(m);
|
||||
|
@ -726,7 +726,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
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);
|
||||
|
@ -740,7 +740,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
// update non-pawn material.
|
||||
if (capture == PAWN)
|
||||
{
|
||||
if (is_enpassant(m))
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
capsq += pawn_push(them);
|
||||
|
||||
|
@ -832,7 +832,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
k ^= zobEp[file_of(st->epSquare)];
|
||||
}
|
||||
|
||||
if (is_promotion(m))
|
||||
if (type_of(m) == PROMOTION)
|
||||
{
|
||||
PieceType promotion = promotion_type(m);
|
||||
|
||||
|
@ -892,7 +892,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
|
|||
|
||||
if (moveIsCheck)
|
||||
{
|
||||
if (is_special(m))
|
||||
if (type_of(m) != NORMAL)
|
||||
st->checkersBB = attackers_to(king_square(them)) & pieces(us);
|
||||
else
|
||||
{
|
||||
|
@ -927,7 +927,7 @@ void Position::undo_move(Move m) {
|
|||
|
||||
sideToMove = ~sideToMove;
|
||||
|
||||
if (is_castle(m))
|
||||
if (type_of(m) == CASTLE)
|
||||
{
|
||||
do_castle_move<false>(m);
|
||||
return;
|
||||
|
@ -945,7 +945,7 @@ void Position::undo_move(Move m) {
|
|||
assert(color_of(piece) == us);
|
||||
assert(capture != KING);
|
||||
|
||||
if (is_promotion(m))
|
||||
if (type_of(m) == PROMOTION)
|
||||
{
|
||||
PieceType promotion = promotion_type(m);
|
||||
|
||||
|
@ -988,7 +988,7 @@ void Position::undo_move(Move m) {
|
|||
{
|
||||
Square capsq = to;
|
||||
|
||||
if (is_enpassant(m))
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
capsq -= pawn_push(us);
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ template<bool Do>
|
|||
void Position::do_castle_move(Move m) {
|
||||
|
||||
assert(is_ok(m));
|
||||
assert(is_castle(m));
|
||||
assert(type_of(m) == CASTLE);
|
||||
|
||||
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
|
||||
|
||||
|
@ -1188,7 +1188,7 @@ int Position::see(Move m) const {
|
|||
// As castle moves are implemented as capturing the rook, they have
|
||||
// SEE == RookValueMidgame most of the times (unless the rook is under
|
||||
// attack).
|
||||
if (is_castle(m))
|
||||
if (type_of(m) == CASTLE)
|
||||
return 0;
|
||||
|
||||
from = from_sq(m);
|
||||
|
@ -1197,7 +1197,7 @@ int Position::see(Move m) const {
|
|||
occ = pieces();
|
||||
|
||||
// Handle en passant moves
|
||||
if (is_enpassant(m))
|
||||
if (type_of(m) == ENPASSANT)
|
||||
{
|
||||
Square capQq = to - pawn_push(sideToMove);
|
||||
|
||||
|
@ -1420,7 +1420,7 @@ bool Position::is_draw() const {
|
|||
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?
|
||||
|
|
|
@ -424,14 +424,14 @@ inline bool Position::is_chess960() const {
|
|||
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));
|
||||
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 {
|
||||
|
|
|
@ -183,7 +183,7 @@ namespace {
|
|||
// Test for a capture that triggers a pawn endgame
|
||||
if ( captureOrPromotion
|
||||
&& type_of(pos.piece_on(to_sq(m))) != PAWN
|
||||
&& !is_special(m)
|
||||
&& 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;
|
||||
|
@ -229,7 +229,7 @@ int64_t Search::perft(Position& pos, Depth depth) {
|
|||
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)
|
||||
|
@ -661,7 +661,7 @@ namespace {
|
|||
&& (ss-1)->eval != VALUE_NONE
|
||||
&& ss->eval != VALUE_NONE
|
||||
&& !pos.captured_piece_type()
|
||||
&& !is_special(move))
|
||||
&& type_of(move) == NORMAL)
|
||||
{
|
||||
Square to = to_sq(move);
|
||||
H.update_gain(pos.piece_on(to), to, -(ss-1)->eval - ss->eval);
|
||||
|
@ -902,7 +902,7 @@ split_point_start: // At split points actual search starts from here
|
|||
&& !inCheck
|
||||
&& !dangerous
|
||||
&& move != ttMove
|
||||
&& !is_castle(move)
|
||||
&& type_of(move) != CASTLE
|
||||
&& (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE))
|
||||
{
|
||||
// Move count based pruning
|
||||
|
@ -961,7 +961,7 @@ split_point_start: // At split points actual search starts from here
|
|||
&& !isPvMove
|
||||
&& !captureOrPromotion
|
||||
&& !dangerous
|
||||
&& !is_castle(move)
|
||||
&& type_of(move) != CASTLE
|
||||
&& ss->killers[0] != move
|
||||
&& ss->killers[1] != move)
|
||||
{
|
||||
|
@ -1226,12 +1226,12 @@ split_point_start: // At split points actual search starts from here
|
|||
&& !givesCheck
|
||||
&& move != ttMove
|
||||
&& enoughMaterial
|
||||
&& !is_promotion(move)
|
||||
&& type_of(move) != PROMOTION
|
||||
&& !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)
|
||||
{
|
||||
|
@ -1259,7 +1259,7 @@ split_point_start: // At split points actual search starts from here
|
|||
if ( !PvNode
|
||||
&& (!inCheck || evasionPrunable)
|
||||
&& move != ttMove
|
||||
&& !is_promotion(move)
|
||||
&& type_of(move) != PROMOTION
|
||||
&& pos.see_sign(move) < 0)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -441,7 +441,7 @@ void ThreadPool::start_searching(const Position& pos, const LimitsType& limits,
|
|||
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()));
|
||||
|
||||
|
|
37
src/types.h
37
src/types.h
|
@ -119,15 +119,13 @@ enum Move {
|
|||
MOVE_NULL = 65
|
||||
};
|
||||
|
||||
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,
|
||||
|
@ -327,6 +325,15 @@ extern const Value PieceValueMidgame[17]; // Indexed by Piece or PieceType
|
|||
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);
|
||||
}
|
||||
|
@ -432,20 +439,8 @@ inline Square to_sq(Move m) {
|
|||
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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue