From 6cd272f7a5ebe53a93c431c655a6fa29a45da2bc Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Fri, 15 Aug 2025 22:35:17 +0200 Subject: [PATCH] Consistently use wrappers around variant properties (#898) * Consistently use wrappers around variant properties instead of a mix of direct and indirect access * Rename drop region fields to follow the color postfix naming convention * Disambiguate the promotionPawnType(s) fields --- src/apiutil.h | 2 +- src/evaluate.cpp | 6 +- src/movegen.cpp | 12 ++-- src/nnue/features/half_ka_v2_variants.cpp | 4 +- src/parser.cpp | 18 ++++--- src/position.cpp | 18 ++++---- src/position.h | 72 ++++++++++++++++++++++++++-- src/psqt.cpp | 2 +- src/variant.cpp | 38 ++++++++-------- src/variant.h | 7 +-- src/variants.ini | 41 ++++++++-------- test.py | 4 +- 12 files changed, 142 insertions(+), 82 deletions(-) diff --git a/src/apiutil.h b/src/apiutil.h index f3003a9..74bdc6d 100644 --- a/src/apiutil.h +++ b/src/apiutil.h @@ -389,7 +389,7 @@ inline bool has_insufficient_material(Color c, const Position& pos) { // Mating pieces for (PieceType pt : { ROOK, QUEEN, ARCHBISHOP, CHANCELLOR, SILVER, GOLD, COMMONER, CENTAUR, AMAZON, BERS }) - if ((pos.pieces(c, pt) & ~restricted) || (pos.count(c, pos.promotion_pawn_type(c)) && (pos.promotion_piece_types(c) & pt))) + if ((pos.pieces(c, pt) & ~restricted) || (pos.count(c, pos.main_promotion_pawn_type(c)) && (pos.promotion_piece_types(c) & pt))) return false; // Color-bound pieces diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 5e49874..ce30aa0 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1074,7 +1074,7 @@ namespace { } // Passed custom pawns - for (PieceSet ps = pos.variant()->promotionPawnTypes[Us] & ~piece_set(PAWN); ps;) + for (PieceSet ps = (pos.promotion_pawn_types(Us) & ~piece_set(PAWN)); ps;) { PieceType pt = pop_lsb(ps); Bitboard b2 = pos.pieces(Us, pt); @@ -1388,8 +1388,8 @@ namespace { // Compute the initiative bonus for the attacking side complexity = 9 * pe->passed_count() - + 12 * pos.count(WHITE, pos.promotion_pawn_type(WHITE)) * bool(pos.promotion_pawn_type(WHITE)) - + 12 * pos.count(BLACK, pos.promotion_pawn_type(BLACK)) * bool(pos.promotion_pawn_type(BLACK)) + + 12 * pos.count(WHITE, pos.main_promotion_pawn_type(WHITE)) * bool(pos.main_promotion_pawn_type(WHITE)) + + 12 * pos.count(BLACK, pos.main_promotion_pawn_type(BLACK)) * bool(pos.main_promotion_pawn_type(BLACK)) + 15 * pos.count() + 9 * outflanking + 21 * pawnsOnBothFlanks diff --git a/src/movegen.cpp b/src/movegen.cpp index f5a16eb..a7b6a9f 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -30,7 +30,7 @@ namespace { // Wall placing moves //if it's "wall or move", and they chose non-null move, skip even generating wall move - if (pos.walling() && !(pos.variant()->wallOrMove && (from!=to))) + if (pos.walling() && !(pos.wall_or_move() && (from!=to))) { Bitboard b = pos.board_bb() & ~((pos.pieces() ^ from) | to); if (T == CASTLING) @@ -47,7 +47,7 @@ namespace { b &= moves_bb(us, type_of(pos.piece_on(from)), to, pos.pieces() ^ from); //Any current or future wall variant must follow the walling region rule if set: - b &= pos.variant()->wallingRegion[us]; + b &= pos.walling_region(us); if (pos.walling_rule() == PAST) b &= square_bb(from); @@ -275,7 +275,7 @@ namespace { Bitboard b = pawns & pawn_attacks_bb(Them, epSquare); // En passant square is already disabled for non-fairy variants if there is no attacker - assert(b || !pos.variant()->fastAttacks); + assert(b || !pos.fast_attacks()); while (b) moveList = make_move_and_gating(pos, moveList, Us, pop_lsb(b), epSquare); @@ -306,8 +306,8 @@ namespace { PieceType promPt = pos.promoted_piece_type(Pt); Bitboard b2 = promPt && (!pos.promotion_limit(promPt) || pos.promotion_limit(promPt) > pos.count(Us, promPt)) ? b1 : Bitboard(0); Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : Bitboard(0); - Bitboard pawnPromotions = pos.variant()->promotionPawnTypes[Us] & Pt ? b & (Type == EVASIONS ? target : ~pos.pieces(Us)) & promotion_zone : Bitboard(0); - Bitboard epSquares = pos.variant()->enPassantTypes[Us] & Pt ? attacks & ~quiets & pos.ep_squares() & ~pos.pieces() : Bitboard(0); + Bitboard pawnPromotions = (pos.promotion_pawn_types(Us) & Pt) ? (b & (Type == EVASIONS ? target : ~pos.pieces(Us)) & promotion_zone) : Bitboard(0); + Bitboard epSquares = (pos.en_passant_types(Us) & Pt) ? (attacks & ~quiets & pos.ep_squares() & ~pos.pieces()) : Bitboard(0); // target squares considering pawn promotions if (pawnPromotions && pos.mandatory_pawn_promotion()) @@ -446,7 +446,7 @@ namespace { *moveList++ = make(lsb(pos.pieces(Us)), lsb(pos.pieces(Us))); //if "wall or move", generate walling action with null move - if (pos.variant()->wallOrMove) + if (pos.wall_or_move()) { moveList = make_move_and_gating(pos, moveList, Us, lsb(pos.pieces(Us)), lsb(pos.pieces(Us))); } diff --git a/src/nnue/features/half_ka_v2_variants.cpp b/src/nnue/features/half_ka_v2_variants.cpp index 1e0fd6e..bf4360a 100644 --- a/src/nnue/features/half_ka_v2_variants.cpp +++ b/src/nnue/features/half_ka_v2_variants.cpp @@ -38,12 +38,12 @@ namespace Stockfish::Eval::NNUE::Features { // Index of a feature for a given king position and another piece on some square inline IndexType HalfKAv2Variants::make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos) { - return IndexType(orient(perspective, s, pos) + pos.variant()->pieceSquareIndex[perspective][pc] + pos.variant()->kingSquareIndex[ksq]); + return IndexType(orient(perspective, s, pos) + pos.nnue_piece_square_index(perspective, pc) + pos.nnue_king_square_index(ksq)); } // Index of a feature for a given king position and another piece on some square inline IndexType HalfKAv2Variants::make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos) { - return IndexType(handCount + pos.variant()->pieceHandIndex[perspective][pc] + pos.variant()->kingSquareIndex[ksq]); + return IndexType(handCount + pos.nnue_piece_hand_index(perspective, pc) + pos.nnue_king_square_index(ksq)); } // Get a list of indices for active features diff --git a/src/parser.cpp b/src/parser.cpp index 3ebf1b1..9f2f848 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -345,14 +345,16 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("blackFlag", v->flagRegion[BLACK]); parse_attribute("castlingRookPiece", v->castlingRookPieces[WHITE], v->pieceToChar); parse_attribute("castlingRookPiece", v->castlingRookPieces[BLACK], v->pieceToChar); + parse_attribute("whiteDropRegion", v->dropRegion[WHITE]); + parse_attribute("blackDropRegion", v->dropRegion[BLACK]); bool dropOnTop = false; parse_attribute("dropOnTop", dropOnTop); if (dropOnTop) v->enclosingDrop=TOP; // Parse aliases - parse_attribute("pawnTypes", v->promotionPawnType[WHITE], v->pieceToChar); - parse_attribute("pawnTypes", v->promotionPawnType[BLACK], v->pieceToChar); + parse_attribute("pawnTypes", v->mainPromotionPawnType[WHITE], v->pieceToChar); + parse_attribute("pawnTypes", v->mainPromotionPawnType[BLACK], v->pieceToChar); parse_attribute("pawnTypes", v->promotionPawnTypes[WHITE], v->pieceToChar); parse_attribute("pawnTypes", v->promotionPawnTypes[BLACK], v->pieceToChar); parse_attribute("pawnTypes", v->enPassantTypes[WHITE], v->pieceToChar); @@ -370,12 +372,12 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("promotionRegionWhite", v->promotionRegion[WHITE]); parse_attribute("promotionRegionBlack", v->promotionRegion[BLACK]); // Take the first promotionPawnTypes as the main promotionPawnType - parse_attribute("promotionPawnTypes", v->promotionPawnType[WHITE], v->pieceToChar); - parse_attribute("promotionPawnTypes", v->promotionPawnType[BLACK], v->pieceToChar); + parse_attribute("promotionPawnTypes", v->mainPromotionPawnType[WHITE], v->pieceToChar); + parse_attribute("promotionPawnTypes", v->mainPromotionPawnType[BLACK], v->pieceToChar); parse_attribute("promotionPawnTypes", v->promotionPawnTypes[WHITE], v->pieceToChar); parse_attribute("promotionPawnTypes", v->promotionPawnTypes[BLACK], v->pieceToChar); - parse_attribute("promotionPawnTypesWhite", v->promotionPawnType[WHITE], v->pieceToChar); - parse_attribute("promotionPawnTypesBlack", v->promotionPawnType[BLACK], v->pieceToChar); + parse_attribute("promotionPawnTypesWhite", v->mainPromotionPawnType[WHITE], v->pieceToChar); + parse_attribute("promotionPawnTypesBlack", v->mainPromotionPawnType[BLACK], v->pieceToChar); parse_attribute("promotionPawnTypesWhite", v->promotionPawnTypes[WHITE], v->pieceToChar); parse_attribute("promotionPawnTypesBlack", v->promotionPawnTypes[BLACK], v->pieceToChar); parse_attribute("promotionPieceTypes", v->promotionPieceTypes[WHITE], v->pieceToChar); @@ -458,8 +460,8 @@ Variant* VariantParser::parse(Variant* v) { parse_attribute("promotionZonePawnDrops", v->promotionZonePawnDrops); parse_attribute("enclosingDrop", v->enclosingDrop); parse_attribute("enclosingDropStart", v->enclosingDropStart); - parse_attribute("whiteDropRegion", v->whiteDropRegion); - parse_attribute("blackDropRegion", v->blackDropRegion); + parse_attribute("dropRegionWhite", v->dropRegion[WHITE]); + parse_attribute("dropRegionBlack", v->dropRegion[BLACK]); parse_attribute("sittuyinRookDrop", v->sittuyinRookDrop); parse_attribute("dropOppositeColoredBishop", v->dropOppositeColoredBishop); parse_attribute("dropPromoted", v->dropPromoted); diff --git a/src/position.cpp b/src/position.cpp index eec715d..c55ab3f 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -76,7 +76,7 @@ std::ostream& operator<<(std::ostream& os, const Position& pos) { os << " *"; else os << " "; - if (!pos.variant()->freeDrops && (pos.piece_drops() || pos.seirawan_gating())) + if (!pos.free_drops() && (pos.piece_drops() || pos.seirawan_gating())) { os << " ["; for (PieceType pt = KING; pt >= PAWN; --pt) @@ -746,7 +746,7 @@ string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string } // pieces in hand - if (!variant()->freeDrops && (piece_drops() || seirawan_gating())) + if (!free_drops() && (piece_drops() || seirawan_gating())) { ss << '['; if (holdings != "-") @@ -1637,7 +1637,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { { Piece pieceToHand = !capturedPromoted || drop_loop() ? ~captured : unpromotedCaptured ? ~unpromotedCaptured - : make_piece(~color_of(captured), promotion_pawn_type(color_of(captured))); + : make_piece(~color_of(captured), main_promotion_pawn_type(color_of(captured))); add_to_hand(pieceToHand); k ^= Zobrist::inHand[pieceToHand][pieceCountInHand[color_of(pieceToHand)][type_of(pieceToHand)] - 1] ^ Zobrist::inHand[pieceToHand][pieceCountInHand[color_of(pieceToHand)][type_of(pieceToHand)]]; @@ -2187,7 +2187,7 @@ void Position::undo_move(Move m) { assert((promotion_zone(us) & to) || sittuyin_promotion()); assert(type_of(pc) == promotion_type(m)); assert(type_of(pc) >= KNIGHT && type_of(pc) < KING); - assert(type_of(st->promotionPawn) == promotion_pawn_type(us) || !captures_to_hand()); + assert(type_of(st->promotionPawn) == main_promotion_pawn_type(us) || !captures_to_hand()); remove_piece(to); pc = st->promotionPawn; @@ -2236,7 +2236,7 @@ void Position::undo_move(Move m) { put_piece(st->capturedPiece, capsq, st->capturedpromoted, st->unpromotedCapturedPiece); // Restore the captured piece if (captures_to_hand()) remove_from_hand(!drop_loop() && st->capturedpromoted ? (st->unpromotedCapturedPiece ? ~st->unpromotedCapturedPiece - : make_piece(~color_of(st->capturedPiece), promotion_pawn_type(us))) + : make_piece(~color_of(st->capturedPiece), main_promotion_pawn_type(us))) : ~st->capturedPiece); } } @@ -2361,7 +2361,7 @@ Key Position::key_after(Move m) const { k ^= Zobrist::psq[captured][to]; if (captures_to_hand()) { - Piece removeFromHand = !drop_loop() && is_promoted(to) ? make_piece(~color_of(captured), promotion_pawn_type(color_of(captured))) : ~captured; + Piece removeFromHand = !drop_loop() && is_promoted(to) ? make_piece(~color_of(captured), main_promotion_pawn_type(color_of(captured))) : ~captured; k ^= Zobrist::inHand[removeFromHand][pieceCountInHand[color_of(removeFromHand)][type_of(removeFromHand)] + 1] ^ Zobrist::inHand[removeFromHand][pieceCountInHand[color_of(removeFromHand)][type_of(removeFromHand)]]; } @@ -2818,7 +2818,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const { { Bitboard b; - for (Direction d : var->connect_directions) + for (Direction d : var->connectDirections) { b = connectPieces; for (int i = 1; i < connect_n() && b; i++) @@ -2838,7 +2838,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const { while (true) { Bitboard newBitboard = 0; - for (Direction d : var->connect_directions) { + for (Direction d : var->connectDirections) { newBitboard |= shift(d, current | newBitboard) & connectPieces; // the "| newBitboard" here probably saves a few loops } @@ -2872,7 +2872,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const { // Collinear-n if (collinear_n() > 0) { Bitboard allPieces = connectPieces; - for (Direction d : var->connect_directions) { + for (Direction d : var->connectDirections) { Bitboard b = allPieces; while (b) { Square s = pop_lsb(b); diff --git a/src/position.h b/src/position.h index 242a4c9..45517d2 100644 --- a/src/position.h +++ b/src/position.h @@ -130,7 +130,7 @@ public: const std::string& piece_to_char_synonyms() const; Bitboard promotion_zone(Color c) const; Square promotion_square(Color c, Square s) const; - PieceType promotion_pawn_type(Color c) const; + PieceType main_promotion_pawn_type(Color c) const; PieceSet promotion_piece_types(Color c) const; bool sittuyin_promotion() const; int promotion_limit(PieceType pt) const; @@ -158,6 +158,12 @@ public: Square nnue_king_square(Color c) const; bool nnue_use_pockets() const; bool nnue_applicable() const; + int nnue_piece_square_index(Color perspective, Piece pc) const; + int nnue_piece_hand_index(Color perspective, Piece pc) const; + int nnue_king_square_index(Square ksq) const; + bool free_drops() const; + bool fast_attacks() const; + bool fast_attacks2() const; bool checking_permitted() const; bool drop_checks() const; bool must_capture() const; @@ -175,10 +181,14 @@ public: bool drop_opposite_colored_bishop() const; bool drop_promoted() const; PieceType drop_no_doubled() const; + PieceSet promotion_pawn_types(Color c) const; + PieceSet en_passant_types(Color c) const; bool immobility_illegal() const; bool gating() const; bool walling() const; WallingRule walling_rule() const; + bool wall_or_move() const; + Bitboard walling_region(Color c) const; bool seirawan_gating() const; bool cambodian_moves() const; Bitboard diagonal_lines() const; @@ -448,9 +458,9 @@ inline Square Position::promotion_square(Color c, Square s) const { return !b ? SQ_NONE : c == WHITE ? lsb(b) : msb(b); } -inline PieceType Position::promotion_pawn_type(Color c) const { +inline PieceType Position::main_promotion_pawn_type(Color c) const { assert(var != nullptr); - return var->promotionPawnType[c]; + return var->mainPromotionPawnType[c]; } inline PieceSet Position::promotion_piece_types(Color c) const { @@ -587,11 +597,41 @@ inline bool Position::nnue_applicable() const { return (!count_in_hand(ALL_PIECES) || nnue_use_pockets() || !must_drop()) && !virtualPieces; } +inline int Position::nnue_piece_square_index(Color perspective, Piece pc) const { + assert(var != nullptr); + return var->pieceSquareIndex[perspective][pc]; +} + +inline int Position::nnue_piece_hand_index(Color perspective, Piece pc) const { + assert(var != nullptr); + return var->pieceHandIndex[perspective][pc]; +} + +inline int Position::nnue_king_square_index(Square ksq) const { + assert(var != nullptr); + return var->kingSquareIndex[ksq]; +} + inline bool Position::checking_permitted() const { assert(var != nullptr); return var->checking; } +inline bool Position::free_drops() const { + assert(var != nullptr); + return var->freeDrops; +} + +inline bool Position::fast_attacks() const { + assert(var != nullptr); + return var->fastAttacks; +} + +inline bool Position::fast_attacks2() const { + assert(var != nullptr); + return var->fastAttacks2; +} + inline bool Position::drop_checks() const { assert(var != nullptr); return var->dropChecks; @@ -660,7 +700,7 @@ inline EnclosingRule Position::enclosing_drop() const { inline Bitboard Position::drop_region(Color c) const { assert(var != nullptr); - return c == WHITE ? var->whiteDropRegion : var->blackDropRegion; + return var->dropRegion[c]; } inline Bitboard Position::drop_region(Color c, PieceType pt) const { @@ -781,6 +821,16 @@ inline PieceType Position::drop_no_doubled() const { return var->dropNoDoubled; } +inline PieceSet Position::promotion_pawn_types(Color c) const { + assert(var != nullptr); + return var->promotionPawnTypes[c]; +} + +inline PieceSet Position::en_passant_types(Color c) const { + assert(var != nullptr); + return var->enPassantTypes[c]; +} + inline bool Position::immobility_illegal() const { assert(var != nullptr); return var->immobilityIllegal; @@ -801,6 +851,16 @@ inline WallingRule Position::walling_rule() const { return var->wallingRule; } +inline bool Position::wall_or_move() const { + assert(var != nullptr); + return var->wallOrMove; +} + +inline Bitboard Position::walling_region(Color c) const { + assert(var != nullptr); + return var->wallingRegion[c]; +} + inline bool Position::seirawan_gating() const { assert(var != nullptr); return var->seirawanGating; @@ -1059,7 +1119,7 @@ inline bool Position::connect_diagonal() const { inline const std::vector& Position::getConnectDirections() const { assert(var != nullptr); - return var->connect_directions; + return var->connectDirections; } inline int Position::connect_nxn() const { @@ -1436,7 +1496,7 @@ inline const std::string Position::piece_to_partner() const { if (!st->capturedPiece) return std::string(); Color color = color_of(st->capturedPiece); Piece piece = st->capturedpromoted ? - (st->unpromotedCapturedPiece ? st->unpromotedCapturedPiece : make_piece(color, promotion_pawn_type(color))) : + (st->unpromotedCapturedPiece ? st->unpromotedCapturedPiece : make_piece(color, main_promotion_pawn_type(color))) : st->capturedPiece; return std::string(1, piece_to_char()[piece]); } diff --git a/src/psqt.cpp b/src/psqt.cpp index 01237dd..d1a84d6 100644 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@ -218,7 +218,7 @@ void init(const Variant* v) { Score score = make_score(PieceValue[MG][pc], PieceValue[EG][pc]); // Consider promotion types in pawn score - if (pt == v->promotionPawnType[WHITE]) + if (pt == v->mainPromotionPawnType[WHITE]) { score -= make_score(0, (QueenValueEg - maxPromotion) / 100); if (v->blastOnCapture) diff --git a/src/variant.cpp b/src/variant.cpp index c3ed05d..c8aa137 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -86,7 +86,7 @@ namespace { Variant* v = chess_variant_base()->init(); v->remove_piece(PAWN); v->add_piece(CUSTOM_PIECE_1, 'p', "mfFcfeWimfnA"); - v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1; + v->mainPromotionPawnType[WHITE] = v->mainPromotionPawnType[BLACK] = CUSTOM_PIECE_1; v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1); @@ -98,7 +98,7 @@ namespace { Variant* v = chess_variant_base()->init(); v->remove_piece(PAWN); v->add_piece(CUSTOM_PIECE_1, 'p', "fsmWfceFifmnD"); - v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1; + v->mainPromotionPawnType[WHITE] = v->mainPromotionPawnType[BLACK] = CUSTOM_PIECE_1; v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1); @@ -112,7 +112,7 @@ namespace { v->add_piece(CUSTOM_PIECE_1, 'p', "fbmWfceFifmnD"); v->mobilityRegion[WHITE][CUSTOM_PIECE_1] = (Rank2BB | Rank3BB | Rank4BB | Rank5BB | Rank6BB | Rank7BB | Rank8BB); v->mobilityRegion[BLACK][CUSTOM_PIECE_1] = (Rank7BB | Rank6BB | Rank5BB | Rank4BB | Rank3BB | Rank2BB | Rank1BB); - v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1; + v->mainPromotionPawnType[WHITE] = v->mainPromotionPawnType[BLACK] = CUSTOM_PIECE_1; v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->enPassantTypes[WHITE] = v->enPassantTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = NO_PIECE_SET; // backwards pawn moves are reversible @@ -126,7 +126,7 @@ namespace { v->add_piece(CUSTOM_PIECE_1, 'p', "mflFcflW"); v->promotionRegion[WHITE] = make_bitboard(SQ_A8, SQ_B8, SQ_C8, SQ_D8, SQ_A7, SQ_A6, SQ_A5); v->promotionRegion[BLACK] = make_bitboard(SQ_E1, SQ_F1, SQ_G1, SQ_H1, SQ_H2, SQ_H3, SQ_H4); - v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = CUSTOM_PIECE_1; + v->mainPromotionPawnType[WHITE] = v->mainPromotionPawnType[BLACK] = CUSTOM_PIECE_1; v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->nMoveRuleTypes[WHITE] = v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->startFen = "knbrp3/bqpp4/npp5/rp1p3P/p3P1PR/5PPN/4PPQB/3PRBNK w - - 0 1"; @@ -689,8 +689,8 @@ namespace { v->mustDrop = true; v->pieceDrops = true; v->capturesToHand = false; - v->whiteDropRegion = Rank1BB; - v->blackDropRegion = Rank8BB; + v->dropRegion[WHITE] = Rank1BB; + v->dropRegion[BLACK] = Rank8BB; v->dropOppositeColoredBishop = true; v->castlingDroppedPiece = true; v->nnueAlias = "nn-"; @@ -708,8 +708,8 @@ namespace { v->mustDrop = true; v->pieceDrops = true; v->capturesToHand = false; - v->whiteDropRegion = Rank1BB | Rank2BB | Rank3BB; - v->blackDropRegion = Rank8BB | Rank7BB | Rank6BB; + v->dropRegion[WHITE] = Rank1BB | Rank2BB | Rank3BB; + v->dropRegion[BLACK] = Rank8BB | Rank7BB | Rank6BB; v->sittuyinRookDrop = true; v->sittuyinPromotion = true; v->promotionRegion[WHITE] = make_bitboard(SQ_A8, SQ_B7, SQ_C6, SQ_D5, SQ_E5, SQ_F6, SQ_G7, SQ_H8); @@ -760,8 +760,8 @@ namespace { v->startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[Dd] w KQkq - 0 1"; v->pieceDrops = true; v->capturesToHand = false; - v->whiteDropRegion = Rank1BB; - v->blackDropRegion = Rank8BB; + v->dropRegion[WHITE] = Rank1BB; + v->dropRegion[BLACK] = Rank8BB; v->promotionPieceTypes[WHITE] = piece_set(ARCHBISHOP) | QUEEN | ROOK | BISHOP | KNIGHT; v->promotionPieceTypes[BLACK] = piece_set(ARCHBISHOP) | QUEEN | ROOK | BISHOP | KNIGHT; return v; @@ -1068,7 +1068,7 @@ namespace { v->add_piece(CUSTOM_PIECE_2, 'l', "FAsmW"); v->add_piece(CUSTOM_PIECE_3, 'c', "WD"); v->startFen = "lgkcckwl/hhhhhhhh/8/8/8/8/PPPPPPPP/RNBQKBNR w KQ - 0 1"; - v->promotionPawnType[BLACK] = CUSTOM_PIECE_1; + v->mainPromotionPawnType[BLACK] = CUSTOM_PIECE_1; v->promotionPawnTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1); v->promotionPieceTypes[BLACK] = piece_set(COMMONER) | DRAGON | ARCHBISHOP | CUSTOM_PIECE_2 | CUSTOM_PIECE_3; @@ -1628,7 +1628,7 @@ namespace { v->add_piece(CUSTOM_PIECE_2, 'n', "NN"); // nightrider v->add_piece(CUSTOM_PIECE_3, 'e', "NNQ"); // elephant v->startFen = "qwfrbbnk/pssppssp/1pp2pp1/8/8/8/8/1PP2PP1/PSSPPSSP/KNBBRFWQ w - - 0 1"; - v->promotionPawnType[WHITE] = v->promotionPawnType[BLACK] = PAWN; + v->mainPromotionPawnType[WHITE] = v->mainPromotionPawnType[BLACK] = PAWN; v->promotionPawnTypes[WHITE] = v->promotionPawnTypes[BLACK] = piece_set(PAWN) | piece_set(CUSTOM_PIECE_1); v->promotionPieceTypes[WHITE] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP; v->promotionPieceTypes[BLACK] = piece_set(QUEEN) | CHANCELLOR | ARCHBISHOP | ROOK | BISHOP; @@ -1748,8 +1748,8 @@ namespace { v->twoBoards = true; v->pieceDrops = true; v->dropChecks = false; - v->whiteDropRegion = v->mobilityRegion[WHITE][ELEPHANT]; - v->blackDropRegion = v->mobilityRegion[BLACK][ELEPHANT]; + v->dropRegion[WHITE] = v->mobilityRegion[WHITE][ELEPHANT]; + v->dropRegion[BLACK] = v->mobilityRegion[BLACK][ELEPHANT]; v->mobilityRegion[WHITE][FERS] = make_bitboard(SQ_D1, SQ_F1, SQ_E2, SQ_D3, SQ_F3); v->mobilityRegion[BLACK][FERS] = make_bitboard(SQ_D8, SQ_F8, SQ_E9, SQ_D10, SQ_F10); v->mobilityRegion[WHITE][ELEPHANT] = make_bitboard(SQ_C1, SQ_G1, SQ_A3, SQ_E3, SQ_I3, SQ_C5, SQ_G5); @@ -2091,19 +2091,19 @@ Variant* Variant::conclude() { break; } - connect_directions.clear(); + connectDirections.clear(); if (connectHorizontal) { - connect_directions.push_back(EAST); + connectDirections.push_back(EAST); } if (connectVertical) { - connect_directions.push_back(NORTH); + connectDirections.push_back(NORTH); } if (connectDiagonal) { - connect_directions.push_back(NORTH_EAST); - connect_directions.push_back(SOUTH_EAST); + connectDirections.push_back(NORTH_EAST); + connectDirections.push_back(SOUTH_EAST); } // If not a connect variant, set connectPieceTypesTrimmed to no pieces. diff --git a/src/variant.h b/src/variant.h index 98fe314..c13305d 100644 --- a/src/variant.h +++ b/src/variant.h @@ -52,7 +52,7 @@ struct Variant { std::string startFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; Bitboard mobilityRegion[COLOR_NB][PIECE_TYPE_NB] = {}; Bitboard promotionRegion[COLOR_NB] = {Rank8BB, Rank1BB}; - PieceType promotionPawnType[COLOR_NB] = {PAWN, PAWN}; + PieceType mainPromotionPawnType[COLOR_NB] = {PAWN, PAWN}; PieceSet promotionPawnTypes[COLOR_NB] = {piece_set(PAWN), piece_set(PAWN)}; PieceSet promotionPieceTypes[COLOR_NB] = {piece_set(QUEEN) | ROOK | BISHOP | KNIGHT, piece_set(QUEEN) | ROOK | BISHOP | KNIGHT}; @@ -97,8 +97,7 @@ struct Variant { bool promotionZonePawnDrops = false; EnclosingRule enclosingDrop = NO_ENCLOSING; Bitboard enclosingDropStart = 0; - Bitboard whiteDropRegion = AllSquares; - Bitboard blackDropRegion = AllSquares; + Bitboard dropRegion[COLOR_NB] = {AllSquares, AllSquares}; bool sittuyinRookDrop = false; bool dropOppositeColoredBishop = false; bool dropPromoted = false; @@ -177,7 +176,7 @@ struct Variant { int nnueMaxPieces; EndgameEval endgameEval = EG_EVAL_CHESS; bool shogiStylePromotions = false; - std::vector connect_directions; + std::vector connectDirections; PieceSet connectPieceTypesTrimmed = ~NO_PIECE_SET; void add_piece(PieceType pt, char c, std::string betza = "", char c2 = ' ') { // Avoid ambiguous definition by removing existing piece with same letter diff --git a/src/variants.ini b/src/variants.ini index 5f17447..24dc66d 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -217,11 +217,10 @@ # capturesToHand: captured pieces go to opponent's hand [bool] (default: false) # firstRankPawnDrops: allow pawn drops to first rank [bool] (default: false) # promotionZonePawnDrops: allow pawn drops in promotion zone [bool] (default: false) -# dropOnTop: DEPRECATED, use "enclosingDrop = top" # enclosingDrop: require piece drop to enclose pieces [EnclosingRule] (default: none) # enclosingDropStart: drop region for starting phase disregarding enclosingDrop (e.g., for reversi) [Bitboard] -# whiteDropRegion: restrict region for piece drops of all white pieces [Bitboard] -# blackDropRegion: restrict region for piece drops of all black pieces [Bitboard] +# dropRegionWhite: restrict region for piece drops of all white pieces [Bitboard] +# dropRegionBlack: restrict region for piece drops of all black pieces [Bitboard] # sittuyinRookDrop: restrict region of rook drops to first rank [bool] (default: false) # dropOppositeColoredBishop: dropped bishops have to be on opposite-colored squares [bool] (default: false) # dropPromoted: pieces may be dropped in promoted state [bool] (default: false) @@ -372,8 +371,8 @@ startFen = rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR[] w - - 0 pieceDrops = true capturesToHand = true dropChecks = false -whiteDropRegion = *1 *2 *3 *4 *5 -blackDropRegion = *6 *7 *8 *9 *10 +dropRegionWhite = *1 *2 *3 *4 *5 +dropRegionBlack = *6 *7 *8 *9 *10 mobilityRegionWhiteFers = d1 f1 e2 d3 f3 mobilityRegionBlackFers = d8 f8 e9 d10 f10 mobilityRegionWhiteElephant = c1 g1 a3 e3 i3 c5 g5 @@ -551,8 +550,8 @@ promotedPieceType = p:c n:g b:a r:m f:q mandatoryPawnPromotion = false firstRankPawnDrops = true promotionZonePawnDrops = true -whiteDropRegion = *1 *2 *3 *4 *5 -blackDropRegion = *4 *5 *6 *7 *8 +dropRegionWhite = *1 *2 *3 *4 *5 +dropRegionBlack = *4 *5 *6 *7 *8 immobilityIllegal = true #https://www.chess.com/variants/caught-in-a-snag @@ -639,7 +638,7 @@ perpetualCheckIllegal = true startFen = rneakenr/8/1c4c1/1ss2ss1/8/8/PPPPPPPP/RNBQKBNR[ss] w KQ - 0 1 flyingGeneral = true capturesToHand = false -blackDropRegion = *5 +dropRegionBlack = *5 flagPiece = k flagRegionWhite = *8 flagRegionBlack = *1 @@ -666,8 +665,8 @@ startFen = RNBKQBNR/pppppppp/8/8/8/8/PPPPPPPP/rnbkqbnr w - - 0 1 [screen:placement] dropNoDoubled = p startFen = 8/8/8/8/8/8/8/8[KQRRBBNNPPPPPPPPkqrrbbnnpppppppp] w - - 0 1 -whiteDropRegion = *1 *2 *3 *4 -blackDropRegion = *8 *7 *6 *5 +dropRegionWhite = *1 *2 *3 *4 +dropRegionBlack = *8 *7 *6 *5 # Crossing chess # https://vchess.club/#/variants/Crossing @@ -791,8 +790,8 @@ stalemateValue = loss perpetualCheckIllegal = true startFen = rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/LH1CK1HL[LHMMDJ] w kq - 0 1 pieceDrops = true -whiteDropRegion = *1 *2 *3 *4 -blackDropRegion = *5 *6 *7 *8 +dropRegionWhite = *1 *2 *3 *4 +dropRegionBlack = *5 *6 *7 *8 immobilityIllegal = true flagPiece = k flagRegionWhite = *8 @@ -1118,8 +1117,8 @@ stalemateValue = loss perpetualCheckIllegal = true startFen = lh1ck1hl/pppppppp/8/8/8/8/PPPPPPPP/LH1CK1HL[LHMMDJlhmmdj] w - - 0 1 capturesToHand = false -whiteDropRegion = *1 *2 *3 *4 -blackDropRegion = *5 *6 *7 *8 +dropRegionWhite = *1 *2 *3 *4 +dropRegionBlack = *5 *6 *7 *8 immobilityIllegal = true flagPiece = k flagRegionWhite = *8 @@ -1219,8 +1218,8 @@ chancellor = c startFen = rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[CAca] w - - 0 1 promotionPieceTypes = qcarbn pieceDrops = true -whiteDropRegion = *1 -blackDropRegion = *8 +dropRegionWhite = *1 +dropRegionBlack = *8 castling = false doubleStep = false stalemateValue = loss @@ -1290,8 +1289,8 @@ customPiece4 = y:mRcD customPiece5 = o:WcF startFen = 3tot3/1p5p1/3XRX3/1d5d1/9/1p1t1t1p1/4d4/9/9/4C4[XXXXYYYYtttttttttd] w - - 0 1 pieceDrops = true -whiteDropRegion = *1 *2 *3 d4 e4 f4 d5 e5 f5 d6 e6 f6 *7 d8 e8 f8 d9 e9 f9 d10 e10 f10 -blackDropRegion = a4 b4 c4 g4 h4 i4 a5 b5 c5 g5 h5 i5 a6 b6 c6 g6 h6 i6 a8 b8 c8 g8 h8 i8 a9 b9 c9 g9 h9 i9 a10 b10 c10 g10 h10 i10 +dropRegionWhite = *1 *2 *3 d4 e4 f4 d5 e5 f5 d6 e6 f6 *7 d8 e8 f8 d9 e9 f9 d10 e10 f10 +dropRegionBlack = a4 b4 c4 g4 h4 i4 a5 b5 c5 g5 h5 i5 a6 b6 c6 g6 h6 i6 a8 b8 c8 g8 h8 i8 a9 b9 c9 g9 h9 i9 a10 b10 c10 g10 h10 i10 castling = false mobilityRegionWhiteCustomPiece3 = *1 *2 *3 *4 a5 c5 d5 e5 f5 g5 i5 *6 *7 *8 a9 c9 d9 e9 f9 g9 i9 *10 # mobilityRegionBlackCustomPiece3 = b5 b9 h5 h9 @@ -1823,8 +1822,8 @@ castling = true castlingRookPieces = r startFen = rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR[MMmm] w KQkq - 0 1 pieceDrops = true -whiteDropRegion = *1 -blackDropRegion = *8 +dropRegionWhite = *1 +dropRegionBlack = *8 #https://www.chessvariants.com/small.dir/petty.html [petty:chess] @@ -1947,7 +1946,7 @@ nFoldRule = 4 perpetualCheckIllegal = true startFen = rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/4K3[JDFCLHM] w kq - 0 1 capturesToHand = false -whiteDropRegion = *1 *2 *3 *4 +dropRegionWhite = *1 *2 *3 *4 immobilityIllegal = true flagPiece = k flagRegionWhite = *8 diff --git a/test.py b/test.py index bef588e..72d61b9 100644 --- a/test.py +++ b/test.py @@ -46,8 +46,8 @@ promotedPieceType = p:c n:g b:a r:m f:q mandatoryPawnPromotion = false firstRankPawnDrops = true promotionZonePawnDrops = true -whiteDropRegion = *1 *2 *3 *4 *5 -blackDropRegion = *4 *5 *6 *7 *8 +dropRegionWhite = *1 *2 *3 *4 *5 +dropRegionBlack = *4 *5 *6 *7 *8 immobilityIllegal = true # Asymmetric variant with one army using pieces that move like knights but attack like other pieces (kniroo and knibis) -- 1.7.0.4