- // evaluate_mobility() computes mobility and attacks for every piece
-
- template<PieceType Piece, Color Us, bool HasPopCnt>
- 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 };
- static const Value* MgBonus[] = { 0, 0, MidgameKnightMobilityBonus, MidgameBishopMobilityBonus, MidgameRookMobilityBonus, MidgameQueenMobilityBonus };
- static const Value* EgBonus[] = { 0, 0, EndgameKnightMobilityBonus, EndgameBishopMobilityBonus, EndgameRookMobilityBonus, EndgameQueenMobilityBonus };
- static const int lastIndex[] = { 0, 0, 8, 15, 15, 31 };
-
- // Update attack info
- ei.attackedBy[Us][Piece] |= b;
-
- // King attacks
- if (b & ei.kingZone[Us])
- {
- ei.kingAttackersCount[Us]++;
- ei.kingAttackersWeight[Us] += AttackWeight[Piece];
- Bitboard bb = (b & ei.attackedBy[Them][KING]);
- if (bb)
- ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15<HasPopCnt>(bb);
- }
-
- // 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);
-
- // Mobility
- int mob = (Piece != QUEEN ? count_1s_max_15<HasPopCnt>(b)
- : count_1s<HasPopCnt>(b));
-
- if (mob > lastIndex[Piece])
- mob = lastIndex[Piece];
-
- ei.mgMobility += Sign[Us] * MgBonus[Piece][mob];
- ei.egMobility += Sign[Us] * EgBonus[Piece][mob];
- return mob;
- }
-
-