assert(pos.is_ok());
assert(threadID >= 0 && threadID < THREAD_MAX);
+ assert(!pos.is_check());
memset(&ei, 0, sizeof(EvalInfo));
// evaluate_mobility() computes mobility and attacks for every piece
template<PieceType Piece, Color Us, bool HasPopCnt>
- int evaluate_mobility(const Position& pos, Bitboard b, EvalInfo& ei) {
+ int evaluate_mobility(const Position& pos, Bitboard b, Bitboard mob_area, EvalInfo& ei) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15<HasPopCnt>(bb);
}
- // Remove squares protected by enemy pawns or occupied by our pieces
- b &= ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
-
// The squares occupied by enemy pieces (not defended by pawns) will be
// counted two times instead of one. The shift (almost) guarantees that
// intersection of the shifted value with b is zero so that after or-ing
// the count of 1s bits is increased by the number of affected squares.
+ b &= mob_area;
b |= Us == WHITE ? ((b & pos.pieces_of_color(Them)) >> 1)
: ((b & pos.pieces_of_color(Them)) << 1);
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Square* ptr = pos.piece_list_begin(Us, Piece);
+ // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
+ const Bitboard mob_area = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
+
while ((s = *ptr++) != SQ_NONE)
{
if (Piece == KNIGHT || Piece == QUEEN)
assert(false);
// Attacks and mobility
- mob = evaluate_mobility<Piece, Us, HasPopCnt>(pos, b, ei);
+ mob = evaluate_mobility<Piece, Us, HasPopCnt>(pos, b, mob_area, ei);
// Bishop and knight outposts squares
if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Them))
Square winnerQSq = relative_square(winnerSide, make_square(square_file(pawnToGo[winnerSide]), RANK_8));
Square loserQSq = relative_square(loserSide, make_square(square_file(pawnToGo[loserSide]), RANK_8));
- Bitboard b = pos.attacks_from<QUEEN>(winnerQSq);
+ Bitboard b = pos.occupied_squares();
+ clear_bit(&b, pawnToGo[winnerSide]);
+ clear_bit(&b, pawnToGo[loserSide]);
+ b = queen_attacks_bb(winnerQSq, b);
if ( (b & pos.pieces(KING, loserSide))
||(bit_is_set(b, loserQSq) && !bit_is_set(ei.attacked_by(loserSide), loserQSq)))