constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
constexpr Bitboard KingFlank[FILE_NB] = {
- QueenSide, QueenSide, QueenSide,
+ QueenSide ^ FileDBB, QueenSide, QueenSide,
CenterFiles, CenterFiles,
- KingSide, KingSide, KingSide
+ KingSide, KingSide, KingSide ^ FileEBB
};
- // Threshold for lazy and space evaluation
- constexpr Value LazyThreshold = Value(1500);
+ // Threshold for space evaluation
constexpr Value SpaceThreshold = Value(12222);
// KingAttackWeights[PieceType] contains king attack weights by piece type
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
- Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safeThreats;
+ Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
Score score = SCORE_ZERO;
+ // Bonuses for variants with mandatory captures
+ if (pos.must_capture())
+ {
+ // Penalties for possible captures
+ score -= make_score(100, 100) * popcount(attackedBy[Us][ALL_PIECES] & pos.pieces(Them));
+
+ // Bonus if we threaten to force captures
+ Bitboard moves = 0, piecebb = pos.pieces(Us);
+ while (piecebb)
+ {
+ Square s = pop_lsb(&piecebb);
+ if (type_of(pos.piece_on(s)) != KING)
+ moves |= pos.moves_from(Us, type_of(pos.piece_on(s)), s);
+ }
+ score += make_score(200, 200) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces());
+ score += make_score(200, 200) * popcount(attackedBy[Them][ALL_PIECES] & moves & ~pos.pieces() & ~attackedBy2[Us]);
+ }
+
// Non-pawn enemies
- nonPawnEnemies = pos.pieces(Them) ^ pos.pieces(Them, PAWN);
+ nonPawnEnemies = pos.pieces(Them) ^ pos.pieces(Them, PAWN, SHOGI_PAWN);
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
b = pawn_attacks_bb<Us>(b) & pos.pieces(Them);
score += ThreatByPawnPush * popcount(b);
+ // Our safe or protected pawns
- b = pos.pieces(Us, PAWN) & safe;
++ b = pos.pieces(Us, PAWN, SHOGI_PAWN) & safe;
+
- b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
++ b = (pawn_attacks_bb<Us>(b) | shift<Up>(pos.pieces(Us, SHOGI_PAWN))) & nonPawnEnemies;
+ score += ThreatBySafePawn * popcount(b);
+
// Bonus for threats on the next moves against enemy queen
if (pos.count<QUEEN>(Them) == 1)
{
Square s = pos.square<QUEEN>(Them);
- safeThreats = mobilityArea[Us] & ~stronglyProtected;
+ safe = mobilityArea[Us] & ~stronglyProtected;
- b = attackedBy[Us][KNIGHT] & pos.attacks_from<KNIGHT>(s);
+ b = attackedBy[Us][KNIGHT] & pos.attacks_from<KNIGHT>(Us, s);
- score += KnightOnQueen * popcount(b & safeThreats);
+ score += KnightOnQueen * popcount(b & safe);
- b = (attackedBy[Us][BISHOP] & pos.attacks_from<BISHOP>(s))
- | (attackedBy[Us][ROOK ] & pos.attacks_from<ROOK >(s));
+ b = (attackedBy[Us][BISHOP] & pos.attacks_from<BISHOP>(Us, s))
+ | (attackedBy[Us][ROOK ] & pos.attacks_from<ROOK >(Us, s));
- score += SliderOnQueen * popcount(b & safeThreats & attackedBy2[Us]);
+ score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
}
if (T)
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
- bb = forward_file_bb(Us, s) & pos.pieces(Them);
- score -= HinderPassedPawn * popcount(bb);
+ if (forward_file_bb(Us, s) & pos.pieces(Them))
+ score -= HinderPassedPawn;
- int r = relative_rank(Us, s);
+ int r = relative_rank(Us, s, pos.max_rank());
int w = PassedDanger[r];
Score bonus = PassedRank[r];