#endif
template <MovementType MT>
- Bitboard sliding_attack(std::map<DirectionCode, int> directions, Square sq, Bitboard occupied, Color c = WHITE) {
- assert(MT != LAME_LEAPER);
-
- Bitboard attack = 0;
+ Bitboard one_ride(DirectionCode v, int limit, Square sq, Bitboard occupied, Color c) {
- for (auto const& [v, limit] : directions)
- {
- int count = 0;
bool hurdle = false;
Direction d = board_step(v);
- for (Square s = sq + (c == WHITE ? d : -d);
- is_ok(s) && distance(s, s - (c == WHITE ? d : -d)) <= 2;
- s += (c == WHITE ? d : -d))
+ int lim = limit;
+ Bitboard attack = 0;
+
+ if(c != WHITE) d = -d;
+ if(MT == HOPPER_RANGE && limit == 0xFFFE) lim = 0; // give grasshopper unlimited total range
+
+ for (Square s = sq + d;
+ is_ok(s) && distance(s, s - d) <= 2;
+ s += d)
{
if (MT != HOPPER || hurdle)
{
- attack |= s;
- // For hoppers we consider limit == 1 as a grasshopper,
- // but limit > 1 as a limited distance hopper
- if (limit && !(MT == HOPPER_RANGE && limit == 1) && ++count >= limit)
- break;
+ if(!(lim & 1)) attack |= s;
+ lim >>= 1;
}
if (occupied & s)
break;
}
}
- }
+ return attack;
+ }
+
+ template <MovementType MT>
+ Bitboard sliding_attack(std::map<DirectionCode, int> directions, Square sq, Bitboard occupied, Color c = WHITE) {
+ assert(MT != LAME_LEAPER);
+
+ Bitboard attack = 0;
+
+ for (auto const& [v, limit] : directions)
+ {
+ attack |= one_ride<MT>(v, limit & 0xFFFF, sq, occupied, c);
+ }
return attack;
}
int slider_fraction(std::map<DirectionCode, int> slider) {
int s = 0;
for (auto const& [_, limit] : slider) {
- s += limit == 0 ? 100 : 200 * std::min(limit + 1, 8) / 16;
+ int targets = popcount(~limit & 0xFFFF); // in reality non-reachable squares should be weighted by distance
+ s += limit == 0 ? 100 : 200 * std::min(targets + 1, 8) / 16;
}
return s;
}