From: H.G.Muller Date: Sat, 3 Jan 2026 21:46:41 +0000 (+0100) Subject: Implement Griffon piece type X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=15268d82d4d3f59d9b81751321d4511489932001;p=fairystockfish.git Implement Griffon piece type Four new RiderTypes are added, using 'tableless magics'. Thai is, they use the attacks tables of the Rook, but shifted by one file or rank. The Betza parser in extended to recognize two-leg moves of teh type yafs..., where yafsF is recognized as the Griffon. It then generates the (fake) large leap that is used to indicate these type of bent slides, omitting moves to the first square of the ride. (Because this is what yafsF means). Unbent moves of the type yaf... are recognized as lame ski-sliders. --- diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 970fe3b..c85dd04 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -54,11 +54,16 @@ Magic NightriderMagics[SQUARE_NB]; 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]; @@ -116,6 +121,10 @@ namespace { const std::map GrasshopperDirectionsH { {step(0, 1), 0xFFFE}, {step(0, -1), 0xFFFE} }; const std::map GrasshopperDirectionsD { {step(1, 1), 0xFFFE}, {step(-1, 1), 0xFFFE}, {step(-1, -1), 0xFFFE}, {step(1, -1), 0xFFFE} }; + const std::map RookDirectionsHT { {step(1, -BENT), 0}, {step(1, BENT), 0} }; + const std::map RookDirectionsHB { {step(-1, -BENT), 0}, {step(-1, BENT), 0} }; + const std::map RookDirectionsVL { {step(-BENT, -1), 0}, {step(BENT, -1), 0} }; + const std::map RookDirectionsVR { {step(-BENT, 1), 0}, {step(BENT, 1), 0} }; const std::map allDirections[] { BishopDirections, RookDirectionsH, RookDirectionsV }; @@ -133,13 +142,23 @@ namespace { 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) { @@ -322,6 +341,14 @@ void Bitboards::init_pieces() { 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]) { @@ -420,6 +447,15 @@ void Bitboards::init() { 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(); diff --git a/src/piece.cpp b/src/piece.cpp index 82a4117..851bbc8 100644 --- a/src/piece.cpp +++ b/src/piece.cpp @@ -64,6 +64,7 @@ namespace { int distance = 0; int fExtension = 0; int fsExtension = 0; + BentType bent = SINGLE_LEG; std::vector prelimDirections = {}; for (std::string::size_type i = 0; i < betza.size(); i++) { @@ -103,6 +104,17 @@ namespace { } 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()) { @@ -141,6 +153,10 @@ namespace { int y = atom.first + 3*fExtension + 2*fsExtension; int x = atom.second + 2*fsExtension; std::vector 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; @@ -197,6 +213,7 @@ namespace { distance = 0; fExtension = 0; fsExtension = 0; + bent = SINGLE_LEG; } } return p; diff --git a/src/piece.h b/src/piece.h index 38fdcc9..d83e5d3 100644 --- a/src/piece.h +++ b/src/piece.h @@ -27,6 +27,8 @@ namespace Stockfish { +const int BENT = 9; // kludge for indicating bent slider as leap + enum MoveModality {MODALITY_QUIET, MODALITY_CAPTURE, MOVE_MODALITY_NB}; /// PieceInfo struct stores information about the piece movements. diff --git a/src/types.h b/src/types.h index aac1085..620e99b 100644 --- a/src/types.h +++ b/src/types.h @@ -450,6 +450,10 @@ enum PieceSet : uint64_t { 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, @@ -466,10 +470,15 @@ enum RiderType : int { 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,