Magic GrasshopperMagicsH[SQUARE_NB];
Magic GrasshopperMagicsV[SQUARE_NB];
Magic GrasshopperMagicsD[SQUARE_NB];
+Magic RookMagicsHT[SQUARE_NB];
+Magic RookMagicsHB[SQUARE_NB];
+Magic RookMagicsVL[SQUARE_NB];
+Magic RookMagicsVR[SQUARE_NB];
Magic CustomMagics[MAX_RIDE - CUSTOM_RIDES][SQUARE_NB];
Magic* magics[MAX_RIDE] = {BishopMagics, RookMagicsH, RookMagicsV, CannonMagicsH, CannonMagicsV,
LameDabbabaMagics, HorseMagics, ElephantMagics, JanggiElephantMagics, CannonDiagMagics, NightriderMagics,
- GrasshopperMagicsH, GrasshopperMagicsV, GrasshopperMagicsD};
+ GrasshopperMagicsH, GrasshopperMagicsV, GrasshopperMagicsD,
+ RookMagicsHT, RookMagicsHB, RookMagicsVL, RookMagicsVR };
int nrOfRides;
int riderBaseType[MAX_RIDE];
const std::map<DirectionCode, int> GrasshopperDirectionsH { {step(0, 1), 0xFFFE}, {step(0, -1), 0xFFFE} };
const std::map<DirectionCode, int> GrasshopperDirectionsD { {step(1, 1), 0xFFFE}, {step(-1, 1), 0xFFFE},
{step(-1, -1), 0xFFFE}, {step(1, -1), 0xFFFE} };
+ const std::map<DirectionCode, int> RookDirectionsHT { {step(1, -BENT), 0}, {step(1, BENT), 0} };
+ const std::map<DirectionCode, int> RookDirectionsHB { {step(-1, -BENT), 0}, {step(-1, BENT), 0} };
+ const std::map<DirectionCode, int> RookDirectionsVL { {step(-BENT, -1), 0}, {step(BENT, -1), 0} };
+ const std::map<DirectionCode, int> RookDirectionsVR { {step(-BENT, 1), 0}, {step(BENT, 1), 0} };
const std::map<DirectionCode, int> allDirections[] { BishopDirections, RookDirectionsH, RookDirectionsV };
bool hurdle = false;
Direction d = board_step(v);
+ Direction x = h_step(v);
+ Direction y = v_step(v);
int lim = limit;
+ Square ss = sq;
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;
+ if(std::abs(x) == BENT) { // bent slider
+ d = x/BENT; ss += y*FILE_NB;
+ } else
+ if(std::abs(y) == BENT) { // bent slider
+ d = y*FILE_NB/BENT; ss += x;
+ }
+
+ for (Square s = ss + d;
is_ok(s) && distance(s, s - d) <= 2;
s += d)
{
riderTypes |= assign_magic(RIDER_ROOK_V, limit);
if (HorseDirections.find(d) != HorseDirections.end())
riderTypes |= RIDER_NIGHTRIDER;
+ if (RookDirectionsHT.find(d) != RookDirectionsHT.end())
+ riderTypes |= RIDER_ROOK_HT;
+ if (RookDirectionsVR.find(d) != RookDirectionsVR.end())
+ riderTypes |= RIDER_ROOK_VR;
+ if (RookDirectionsHB.find(d) != RookDirectionsHB.end())
+ riderTypes |= RIDER_ROOK_HB;
+ if (RookDirectionsVL.find(d) != RookDirectionsVL.end())
+ riderTypes |= RIDER_ROOK_VL;
}
for (auto const& [d, limit] : pi->hopper[initial][modality])
{
nrOfRides = CUSTOM_RIDES;
for(int i = 0; i < CUSTOM_RIDES; i++) riderBaseType[i] = i;
++
+ // Magics that can use attacks tables from others
+ for(Square s = SQ_A1; s <= SQ_MAX; ++s)
+ {
+ RookMagicsHT[s] = RookMagicsH[rank_of(s) < RANK_NB - 1 ? s + FILE_NB : s - FILE_NB];
+ RookMagicsHB[s] = RookMagicsH[rank_of(s) > 0 ? s - FILE_NB : s + FILE_NB];
+ RookMagicsVR[s] = RookMagicsV[file_of(s) < FILE_NB - 1 ? s + 1 : s - 1];
+ RookMagicsVL[s] = RookMagicsV[file_of(s) > 0 ? s - 1 : s + 1];
+ }
init_pieces();
int distance = 0;
int fExtension = 0;
int fsExtension = 0;
+ BentType bent = SINGLE_LEG;
std::vector<std::string> prelimDirections = {};
for (std::string::size_type i = 0; i < betza.size(); i++)
{
}
prelimDirections.push_back(std::string(2, c));
}
+ // Multi-leg
+ else if(betza.size() > i + 3 && (c == 'a' || (c == 'y' && betza[++i] == 'a'))) // detect yaf(s)
+ {
+ if(betza[i+1] == 'f' && c == 'y')
+ {
+ if(betza[i+2] == 's') { i++; bent = BENT_SLIDER; }
+ else bent = SKI_SLIDER;
+ i++; distance |= 1; // suppress 1-step moves
+ moveModalities.clear();
+ }
+ }
// Move atom
else if (leaperAtoms.find(c) != leaperAtoms.end() || riderAtoms.find(c) != riderAtoms.end())
{
int y = atom.first + 3*fExtension + 2*fsExtension;
int x = atom.second + 2*fsExtension;
std::vector<std::string> directions = {};
+ if(bent != SINGLE_LEG) {
+ if(bent == BENT_SLIDER && c == 'F') y = BENT; // yafsF = griffon
+ rider = true;
+ }
if(rider && y > 1 && (x == 0 || x == y)) { // radial true rider
for(int n = distance; ~n & 1; n >>= 1) distance <<= y - 1; // adapt range to larger stride
distance &= 0xFFFF;
distance = 0;
fExtension = 0;
fsExtension = 0;
+ bent = SINGLE_LEG;
}
}
return p;
COMMON_STEP_PIECES = (1ULL << COMMONER) | (1ULL << FERS) | (1ULL << WAZIR) | (1ULL << BREAKTHROUGH_PIECE),
};
+enum BentType : int {
+ SINGLE_LEG, SKI_SLIDER, BENT_SLIDER, HOOK_MOVER
+};
+
enum RiderType : int {
NO_RIDER = 0,
RIDER_BISHOP = 1 << 0,
RIDER_GRASSHOPPER_H = 1 << 11,
RIDER_GRASSHOPPER_V = 1 << 12,
RIDER_GRASSHOPPER_D = 1 << 13,
+ RIDER_ROOK_HT = 1 << 14,
+ RIDER_ROOK_HB = 1 << 15,
+ RIDER_ROOK_VL = 1 << 16,
+ RIDER_ROOK_VR = 1 << 17,
+ RIDER_GRIFFON = RIDER_ROOK_HT | RIDER_ROOK_HB | RIDER_ROOK_VL | RIDER_ROOK_VR,
HOPPING_RIDERS = RIDER_CANNON_H | RIDER_CANNON_V | RIDER_CANNON_DIAG
| RIDER_GRASSHOPPER_H | RIDER_GRASSHOPPER_V | RIDER_GRASSHOPPER_D,
LAME_LEAPERS = RIDER_LAME_DABBABA | RIDER_HORSE | RIDER_ELEPHANT | RIDER_JANGGI_ELEPHANT,
- ASYMMETRICAL_RIDERS = RIDER_HORSE | RIDER_JANGGI_ELEPHANT
+ ASYMMETRICAL_RIDERS = RIDER_HORSE | RIDER_JANGGI_ELEPHANT | GRIFFON
| RIDER_GRASSHOPPER_H | RIDER_GRASSHOPPER_V | RIDER_GRASSHOPPER_D,
NON_SLIDING_RIDERS = HOPPING_RIDERS | LAME_LEAPERS | RIDER_NIGHTRIDER,
CUSTOM_RIDES = 20,