No functional change.
template<> inline int distance<Rank>(Square x, Square y) { return std::abs(rank_of(x) - rank_of(y)); }
template<> inline int distance<Square>(Square x, Square y) { return SquareDistance[x][y]; }
- template<class T> constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
- return v < lo ? lo : v > hi ? hi : v;
- }
+
+template<RiderType R>
+inline Bitboard rider_attacks_bb(Square s, Bitboard occupied) {
+
+ assert(R == RIDER_BISHOP || R == RIDER_ROOK_H || R == RIDER_ROOK_V || R == RIDER_CANNON_H || R == RIDER_CANNON_V
+ || R == RIDER_HORSE || R == RIDER_ELEPHANT || R == RIDER_JANGGI_ELEPHANT);
+ const Magic& m = R == RIDER_ROOK_H ? RookMagicsH[s]
+ : R == RIDER_ROOK_V ? RookMagicsV[s]
+ : R == RIDER_CANNON_H ? CannonMagicsH[s]
+ : R == RIDER_CANNON_V ? CannonMagicsV[s]
+ : R == RIDER_HORSE ? HorseMagics[s]
+ : R == RIDER_ELEPHANT ? ElephantMagics[s]
+ : R == RIDER_JANGGI_ELEPHANT ? JanggiElephantMagics[s]
+ : BishopMagics[s];
+ return m.attacks[m.index(occupied)];
+}
+
/// attacks_bb() returns a bitboard representing all the squares attacked by a
/// piece of type Pt (bishop or rook) placed on 's'.
// Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
// or controlled by enemy pawns are excluded from the mobility area.
- mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
+ if (pos.must_capture())
+ mobilityArea[Us] = AllSquares;
+ else
+ mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them)
+ | shift<Down>(pos.pieces(Them, SHOGI_PAWN, SOLDIER))
+ | shift<EAST>(pos.promoted_soldiers(Them))
+ | shift<WEST>(pos.promoted_soldiers(Them)));
// Initialize attackedBy[] for king and pawns
- attackedBy[Us][KING] = pos.attacks_from<KING>(ksq);
+ attackedBy[Us][KING] = pos.count<KING>(Us) ? pos.attacks_from<KING>(ksq, Us) : Bitboard(0);
attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
- attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
- attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
+ attackedBy[Us][SHOGI_PAWN] = shift<Up>(pos.pieces(Us, SHOGI_PAWN));
+ attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN];
+ attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN])
+ | (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN])
+ | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN])
+ | dblAttackByPawn;
// Init our king safety tables
- Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
- Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
- kingRing[Us] = PseudoAttacks[KING][s] | s;
+ if (!pos.count<KING>(Us))
+ kingRing[Us] = Bitboard(0);
+ else
+ {
- Square s = make_square(clamp(file_of(ksq), FILE_B, File(pos.max_file() - 1)),
- clamp(rank_of(ksq), RANK_2, Rank(pos.max_rank() - 1)));
++ Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, File(pos.max_file() - 1)),
++ Utility::clamp(rank_of(ksq), RANK_2, Rank(pos.max_rank() - 1)));
+ kingRing[Us] = PseudoAttacks[Us][KING][s] | s;
+ }
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
Value npm_w = pos.non_pawn_material(WHITE);
Value npm_b = pos.non_pawn_material(BLACK);
- Value npm = clamp(npm_w + npm_b, EndgameLimit, MidgameLimit);
+ Value npm = Utility::clamp(npm_w + npm_b, EndgameLimit, MidgameLimit);
// Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME]
- e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
+ if (pos.captures_to_hand())
+ {
+ Value npm2 = VALUE_ZERO;
+ for (PieceType pt : pos.piece_types())
+ npm2 += (pos.count_in_hand(WHITE, pt) + pos.count_in_hand(BLACK, pt)) * PieceValue[MG][make_piece(WHITE, pt)];
+ e->gamePhase = Phase(PHASE_MIDGAME * npm / std::max(int(npm + npm2), 1));
+ }
+ else
+ e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
+ if (pos.endgame_eval())
+ {
// Let's look if we have a specialized evaluation function for this particular
// material configuration. Firstly we look for a fixed configuration one, then
// for a generic one if the previous search failed.
Score bonus = make_score(5, 5);
- File center = clamp(file_of(ksq), FILE_B, File(pos.max_file() - 1));
- File center = Utility::clamp(file_of(ksq), FILE_B, FILE_G);
++ File center = Utility::clamp(file_of(ksq), FILE_B, File(pos.max_file() - 1));
for (File f = File(center - 1); f <= File(center + 1); ++f)
{
b = ourPawns & file_bb(f);